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/types.h>
21 #include <tools/fontenum.hxx>
22 #include <unotools/fontdefs.hxx>
23 
24 #include <fontattributes.hxx>
25 #include <fontselect.hxx>
26 
27 #include <PhysicalFontFace.hxx>
28 
30  : FontAttributes( rDFA )
31  , mnWidth(0)
32  , mnHeight(0)
33 {
34  // StarSymbol is a unicode font, but it still deserves the symbol flag
35  if( !IsSymbolFont() )
36  if ( IsStarSymbol( GetFamilyName() ) )
37  SetSymbolFlag( true );
38 }
39 
40 sal_Int32 PhysicalFontFace::CompareIgnoreSize( const PhysicalFontFace& rOther ) const
41 {
42  // compare their width, weight, italic, style name and family name
43  if( GetWidthType() < rOther.GetWidthType() )
44  return -1;
45  else if( GetWidthType() > rOther.GetWidthType() )
46  return 1;
47 
48  if( GetWeight() < rOther.GetWeight() )
49  return -1;
50  else if( GetWeight() > rOther.GetWeight() )
51  return 1;
52 
53  if( GetItalic() < rOther.GetItalic() )
54  return -1;
55  else if( GetItalic() > rOther.GetItalic() )
56  return 1;
57 
58  sal_Int32 nRet = GetFamilyName().compareTo( rOther.GetFamilyName() );
59 
60  if (nRet == 0)
61  {
62  nRet = GetStyleName().compareTo( rOther.GetStyleName() );
63  }
64 
65  return nRet;
66 }
67 
68 sal_Int32 PhysicalFontFace::CompareWithSize( const PhysicalFontFace& rOther ) const
69 {
70  sal_Int32 nCompare = CompareIgnoreSize( rOther );
71  if (nCompare != 0)
72  return nCompare;
73 
74  if( mnHeight < rOther.mnHeight )
75  return -1;
76  else if( mnHeight > rOther.mnHeight )
77  return 1;
78 
79  if( mnWidth < rOther.mnWidth )
80  return -1;
81  else if( mnWidth > rOther.mnWidth )
82  return 1;
83 
84  return 0;
85 }
86 
88 {
89  int nMatch = 0;
90 
91  const OUString& rFontName = rFSD.maTargetName;
92  if( rFontName.equalsIgnoreAsciiCase( GetFamilyName() ) )
93  nMatch += 240000;
94 
95  if( rStatus.mpTargetStyleName
96  && GetStyleName().equalsIgnoreAsciiCase( *rStatus.mpTargetStyleName ) )
97  nMatch += 120000;
98 
99  if( (rFSD.GetPitch() != PITCH_DONTKNOW) && (rFSD.GetPitch() == GetPitch()) )
100  nMatch += 20000;
101 
102  // prefer NORMAL font width
103  // TODO: change when the upper layers can tell their width preference
104  if( GetWidthType() == WIDTH_NORMAL )
105  nMatch += 400;
107  nMatch += 300;
108 
109  if( rFSD.GetWeight() != WEIGHT_DONTKNOW )
110  {
111  // if not bold or requiring emboldening prefer light fonts to bold fonts
112  FontWeight ePatternWeight = rFSD.mbEmbolden ? WEIGHT_NORMAL : rFSD.GetWeight();
113 
114  int nReqWeight = static_cast<int>(ePatternWeight);
115  if ( ePatternWeight > WEIGHT_MEDIUM )
116  nReqWeight += 100;
117 
118  int nGivenWeight = static_cast<int>(GetWeight());
119  if( GetWeight() > WEIGHT_MEDIUM )
120  nGivenWeight += 100;
121 
122  int nWeightDiff = nReqWeight - nGivenWeight;
123 
124  if ( nWeightDiff == 0 )
125  nMatch += 1000;
126  else if ( nWeightDiff == +1 || nWeightDiff == -1 )
127  nMatch += 700;
128  else if ( nWeightDiff < +50 && nWeightDiff > -50)
129  nMatch += 200;
130  }
131  else // requested weight == WEIGHT_DONTKNOW
132  {
133  // prefer NORMAL font weight
134  // TODO: change when the upper layers can tell their weight preference
135  if( GetWeight() == WEIGHT_NORMAL )
136  nMatch += 450;
137  else if( GetWeight() == WEIGHT_MEDIUM )
138  nMatch += 350;
139  else if( (GetWeight() == WEIGHT_SEMILIGHT) || (GetWeight() == WEIGHT_SEMIBOLD) )
140  nMatch += 200;
141  else if( GetWeight() == WEIGHT_LIGHT )
142  nMatch += 150;
143  }
144 
145  // if requiring custom matrix to fake italic, prefer upright font
146  FontItalic ePatternItalic = rFSD.maItalicMatrix != ItalicMatrix() ? ITALIC_NONE : rFSD.GetItalic();
147 
148  if ( ePatternItalic == ITALIC_NONE )
149  {
150  if( GetItalic() == ITALIC_NONE )
151  nMatch += 900;
152  }
153  else
154  {
155  if( ePatternItalic == GetItalic() )
156  nMatch += 900;
157  else if( GetItalic() != ITALIC_NONE )
158  nMatch += 600;
159  }
160 
161  int nHeightMatch = 0;
162  int nWidthMatch = 0;
163 
164  if( rFSD.mnOrientation != 0 )
165  nMatch += 80;
166  else if( rFSD.mnWidth != 0 )
167  nMatch += 25;
168  else
169  nMatch += 5;
170 
171  if( rStatus.mnFaceMatch > nMatch )
172  return false;
173  else if( rStatus.mnFaceMatch < nMatch )
174  {
175  rStatus.mnFaceMatch = nMatch;
176  rStatus.mnHeightMatch = nHeightMatch;
177  rStatus.mnWidthMatch = nWidthMatch;
178  return true;
179  }
180 
181  // when two fonts are still competing prefer the
182  // one with the best matching height
183  if( rStatus.mnHeightMatch > nHeightMatch )
184  return false;
185  else if( rStatus.mnHeightMatch < nHeightMatch )
186  {
187  rStatus.mnHeightMatch = nHeightMatch;
188  rStatus.mnWidthMatch = nWidthMatch;
189  return true;
190  }
191 
192  if( rStatus.mnWidthMatch > nWidthMatch )
193  return false;
194 
195  rStatus.mnWidthMatch = nWidthMatch;
196  return true;
197 }
198 
199 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
double mnHeight
const OUString & GetStyleName() const
WIDTH_NORMAL
WEIGHT_SEMIBOLD
WIDTH_SEMI_EXPANDED
WEIGHT_LIGHT
const OUString * mpTargetStyleName
ItalicMatrix maItalicMatrix
Definition: fontselect.hxx:68
PhysicalFontFace(const FontAttributes &)
FontItalic GetItalic() const
abstract base class for physical font faces
WEIGHT_DONTKNOW
WEIGHT_SEMILIGHT
FontWeight GetWeight() const
WEIGHT_MEDIUM
bool IsBetterMatch(const FontSelectPattern &, FontMatchStatus &) const
WEIGHT_NORMAL
void SetSymbolFlag(const bool)
PITCH_DONTKNOW
ITALIC_NONE
FontWeight
double mnWidth
FontWidth GetWidthType() const
bool IsSymbolFont() const
FontPitch GetPitch() const
bool IsStarSymbol(const OUString &rFontName)
WIDTH_SEMI_CONDENSED
const OUString & GetFamilyName() const
OUString maTargetName
Definition: fontselect.hxx:57
sal_Int32 CompareWithSize(const PhysicalFontFace &) const
FontItalic
sal_Int32 CompareIgnoreSize(const PhysicalFontFace &) const