LibreOffice Module vcl (master) 1
PhysicalFontFace.cxx
Go to the documentation of this file.
1/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2/*
3 * This file is part of the LibreOffice project.
4 *
5 * This Source Code Form is subject to the terms of the Mozilla Public
6 * License, v. 2.0. If a copy of the MPL was not distributed with this
7 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
8 *
9 * This file incorporates work covered by the following license notice:
10 *
11 * Licensed to the Apache Software Foundation (ASF) under one or more
12 * contributor license agreements. See the NOTICE file distributed
13 * with this work for additional information regarding copyright
14 * ownership. The ASF licenses this file to you under the Apache
15 * License, Version 2.0 (the "License"); you may not use this file
16 * except in compliance with the License. You may obtain a copy of
17 * the License at http://www.apache.org/licenses/LICENSE-2.0 .
18 */
19
20#include <sal/config.h>
21
22#include <sal/types.h>
23#include <tools/fontenum.hxx>
24#include <unotools/fontdefs.hxx>
25
26#include <fontattributes.hxx>
27
30#include <o3tl/string_view.hxx>
31
32#include <string_view>
33
34namespace vcl::font
35{
36
38 : FontAttributes( rDFA )
39{
40 // StarSymbol is a unicode font, but it still deserves the symbol flag
41 if( !IsSymbolFont() )
42 if ( IsStarSymbol( GetFamilyName() ) )
43 SetSymbolFlag( true );
44}
45
47{
48 // compare their width, weight, italic, style name and family name
49 if( GetWidthType() < rOther.GetWidthType() )
50 return -1;
51 else if( GetWidthType() > rOther.GetWidthType() )
52 return 1;
53
54 if( GetWeight() < rOther.GetWeight() )
55 return -1;
56 else if( GetWeight() > rOther.GetWeight() )
57 return 1;
58
59 if( GetItalic() < rOther.GetItalic() )
60 return -1;
61 else if( GetItalic() > rOther.GetItalic() )
62 return 1;
63
64 sal_Int32 nRet = GetFamilyName().compareTo( rOther.GetFamilyName() );
65
66 if (nRet == 0)
67 {
68 nRet = GetStyleName().compareTo( rOther.GetStyleName() );
69 }
70
71 return nRet;
72}
73
74static int FamilyNameMatchValue(FontSelectPattern const& rFSP, std::u16string_view sFontFamily)
75{
76 const OUString& rFontName = rFSP.maTargetName;
77
78 if (rFontName.equalsIgnoreAsciiCase(sFontFamily))
79 return 240000;
80
81 return 0;
82}
83
84static int StyleNameMatchValue(FontMatchStatus const& rStatus, std::u16string_view rStyle)
85{
87 return 120000;
88
89 return 0;
90}
91
92static int PitchMatchValue(FontSelectPattern const& rFSP, FontPitch ePitch)
93{
94 if ((rFSP.GetPitch() != PITCH_DONTKNOW) && (rFSP.GetPitch() == ePitch))
95 return 20000;
96
97 return 0;
98}
99
101{
102 // TODO: change when the upper layers can tell their width preference
103 if (eWidthType == WIDTH_NORMAL)
104 return 400;
105 else if ((eWidthType == WIDTH_SEMI_EXPANDED) || (eWidthType == WIDTH_SEMI_CONDENSED))
106 return 300;
107
108 return 0;
109}
110
111static int WeightMatchValue(FontSelectPattern const& rFSP, FontWeight eWeight)
112{
113 int nMatch = 0;
114
115 if (rFSP.GetWeight() != WEIGHT_DONTKNOW)
116 {
117 // if not bold or requiring emboldening prefer light fonts to bold fonts
118 FontWeight ePatternWeight = rFSP.mbEmbolden ? WEIGHT_NORMAL : rFSP.GetWeight();
119
120 int nReqWeight = static_cast<int>(ePatternWeight);
121 if (ePatternWeight > WEIGHT_MEDIUM)
122 nReqWeight += 100;
123
124 int nGivenWeight = static_cast<int>(eWeight);
125 if (eWeight > WEIGHT_MEDIUM)
126 nGivenWeight += 100;
127
128 int nWeightDiff = nReqWeight - nGivenWeight;
129
130 if (nWeightDiff == 0)
131 nMatch += 1000;
132 else if (nWeightDiff == +1 || nWeightDiff == -1)
133 nMatch += 700;
134 else if (nWeightDiff < +50 && nWeightDiff > -50)
135 nMatch += 200;
136 }
137 else
138 {
139 // prefer NORMAL font weight
140 // TODO: change when the upper layers can tell their weight preference
141 if (eWeight == WEIGHT_NORMAL)
142 nMatch += 450;
143 else if (eWeight == WEIGHT_MEDIUM)
144 nMatch += 350;
145 else if ((eWeight == WEIGHT_SEMILIGHT) || (eWeight == WEIGHT_SEMIBOLD))
146 nMatch += 200;
147 else if (eWeight == WEIGHT_LIGHT)
148 nMatch += 150;
149 }
150
151 return nMatch;
152}
153
154static int ItalicMatchValue(FontSelectPattern const& rFSP, FontItalic eItalic)
155{
156 // if requiring custom matrix to fake italic, prefer upright font
157 FontItalic ePatternItalic
158 = rFSP.maItalicMatrix != ItalicMatrix() ? ITALIC_NONE : rFSP.GetItalic();
159
160 if (ePatternItalic == ITALIC_NONE)
161 {
162 if (eItalic == ITALIC_NONE)
163 return 900;
164 }
165 else
166 {
167 if (ePatternItalic == eItalic)
168 return 900;
169 else if (eItalic != ITALIC_NONE)
170 return 600;
171 }
172
173 return 0;
174}
175
177{
178 int nMatch = FamilyNameMatchValue(rFSP, GetFamilyName());
179 nMatch += StyleNameMatchValue(rStatus, GetStyleName());
180 nMatch += PitchMatchValue(rFSP, GetPitch());
182 nMatch += WeightMatchValue(rFSP, GetWeight());
183 nMatch += ItalicMatchValue(rFSP, GetItalic());
184
185 if (rFSP.mnOrientation != 0_deg10)
186 nMatch += 80;
187 else if (rFSP.mnWidth != 0)
188 nMatch += 25;
189 else
190 nMatch += 5;
191
192 if( rStatus.mnFaceMatch > nMatch )
193 {
194 return false;
195 }
196 else if( rStatus.mnFaceMatch < nMatch )
197 {
198 rStatus.mnFaceMatch = nMatch;
199 return true;
200 }
201
202 return true;
203}
204}
205
206/* vim:set shiftwidth=4 softtabstop=4 expandtab cinoptions=b1,g0,N-s cinkeys+=0=break: */
bool IsSymbolFont() const
FontItalic GetItalic() const
FontWeight GetWeight() const
const OUString & GetFamilyName() const
FontPitch GetPitch() const
void SetSymbolFlag(const bool)
const OUString & GetStyleName() const
FontWidth GetWidthType() const
abstract base class for physical font faces
sal_Int32 CompareIgnoreSize(const PhysicalFontFace &) const
PhysicalFontFace(const FontAttributes &)
bool IsBetterMatch(const vcl::font::FontSelectPattern &, FontMatchStatus &) const
UNOTOOLS_DLLPUBLIC bool IsStarSymbol(std::u16string_view rFontName)
FontPitch
PITCH_DONTKNOW
FontItalic
ITALIC_NONE
FontWidth
WIDTH_SEMI_CONDENSED
WIDTH_SEMI_EXPANDED
WIDTH_NORMAL
WEIGHT_NORMAL
WEIGHT_LIGHT
WEIGHT_DONTKNOW
WEIGHT_SEMIBOLD
WEIGHT_SEMILIGHT
WEIGHT_MEDIUM
bool equalsIgnoreAsciiCase(std::u16string_view s1, std::u16string_view s2)
FontWeight
A PhysicalFontFaceCollection is created by a PhysicalFontCollection and becomes invalid when original...
static int ItalicMatchValue(FontSelectPattern const &rFSP, FontItalic eItalic)
static int WeightMatchValue(FontSelectPattern const &rFSP, FontWeight eWeight)
static int PreferNormalFontWidthMatchValue(FontWidth eWidthType)
static int PitchMatchValue(FontSelectPattern const &rFSP, FontPitch ePitch)
static int FamilyNameMatchValue(FontSelectPattern const &rFSP, std::u16string_view sFontFamily)
static int StyleNameMatchValue(FontMatchStatus const &rStatus, std::u16string_view rStyle)
const OUString * mpTargetStyleName