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 <tools/stream.hxx>
21 #include <tools/vcompat.hxx>
22 #include <tools/gen.hxx>
23 #include <unotools/fontcfg.hxx>
24 #include <unotools/fontdefs.hxx>
25
26 #include <vcl/font.hxx>
27 #include <vcl/svapp.hxx>
28 #include <vcl/outdev.hxx>
29 #include <vcl/virdev.hxx>
30
31 #include <impfont.hxx>
32 #include <fontattributes.hxx>
33 #include <sft.hxx>
34
35 #include <algorithm>
36 #include <string_view>
37
38 #include <rtl/instance.hxx>
39 #include <vcl/TypeSerializer.hxx>
40
41 #ifdef _WIN32
42 #include <vcl/metric.hxx>
43 #endif
44
45 using namespace vcl;
46
47 namespace
48 {
49 struct theGlobalDefault :
50 public rtl::Static< Font::ImplType, theGlobalDefault > {};
51 }
52
Font()53 Font::Font() : mpImplFont(theGlobalDefault::get())
54 {
55 }
56
Font(const vcl::Font & rFont)57 Font::Font( const vcl::Font& rFont ) : mpImplFont( rFont.mpImplFont )
58 {
59 }
60
Font(vcl::Font && rFont)61 Font::Font( vcl::Font&& rFont ) noexcept : mpImplFont( std::move(rFont.mpImplFont) )
62 {
63 }
64
Font(const OUString & rFamilyName,const Size & rSize)65 Font::Font( const OUString& rFamilyName, const Size& rSize ) : mpImplFont()
66 {
67 mpImplFont->SetFamilyName( rFamilyName );
68 mpImplFont->SetFontSize( rSize );
69 }
70
Font(const OUString & rFamilyName,const OUString & rStyleName,const Size & rSize)71 Font::Font( const OUString& rFamilyName, const OUString& rStyleName, const Size& rSize ) : mpImplFont()
72 {
73 mpImplFont->SetFamilyName( rFamilyName );
74 mpImplFont->SetStyleName( rStyleName );
75 mpImplFont->SetFontSize( rSize );
76 }
77
Font(FontFamily eFamily,const Size & rSize)78 Font::Font( FontFamily eFamily, const Size& rSize ) : mpImplFont()
79 {
80 mpImplFont->SetFamilyType( eFamily );
81 mpImplFont->SetFontSize( rSize );
82 }
83
~Font()84 Font::~Font()
85 {
86 }
87
SetColor(const Color & rColor)88 void Font::SetColor( const Color& rColor )
89 {
90 if (const_cast<const ImplType&>(mpImplFont)->maColor != rColor)
91 {
92 mpImplFont->maColor = rColor;
93 }
94 }
95
SetFillColor(const Color & rColor)96 void Font::SetFillColor( const Color& rColor )
97 {
98 mpImplFont->maFillColor = rColor;
99 if ( rColor.IsTransparent() )
100 mpImplFont->mbTransparent = true;
101 }
102
SetTransparent(bool bTransparent)103 void Font::SetTransparent( bool bTransparent )
104 {
105 if (const_cast<const ImplType&>(mpImplFont)->mbTransparent != bTransparent)
106 mpImplFont->mbTransparent = bTransparent;
107 }
108
SetAlignment(FontAlign eAlign)109 void Font::SetAlignment( FontAlign eAlign )
110 {
111 if (const_cast<const ImplType&>(mpImplFont)->meAlign != eAlign)
112 mpImplFont->SetAlignment(eAlign);
113 }
114
SetFamilyName(const OUString & rFamilyName)115 void Font::SetFamilyName( const OUString& rFamilyName )
116 {
117 mpImplFont->SetFamilyName( rFamilyName );
118 }
119
SetStyleName(const OUString & rStyleName)120 void Font::SetStyleName( const OUString& rStyleName )
121 {
122 mpImplFont->maStyleName = rStyleName;
123 }
124
SetFontSize(const Size & rSize)125 void Font::SetFontSize( const Size& rSize )
126 {
127 if (const_cast<const ImplType&>(mpImplFont)->GetFontSize() != rSize)
128 mpImplFont->SetFontSize( rSize );
129 }
130
SetFamily(FontFamily eFamily)131 void Font::SetFamily( FontFamily eFamily )
132 {
133 if (const_cast<const ImplType&>(mpImplFont)->GetFamilyTypeNoAsk() != eFamily)
134 mpImplFont->SetFamilyType( eFamily );
135 }
136
SetCharSet(rtl_TextEncoding eCharSet)137 void Font::SetCharSet( rtl_TextEncoding eCharSet )
138 {
139 if (const_cast<const ImplType&>(mpImplFont)->GetCharSet() != eCharSet)
140 {
141 mpImplFont->SetCharSet( eCharSet );
142
143 if ( eCharSet == RTL_TEXTENCODING_SYMBOL )
144 mpImplFont->SetSymbolFlag( true );
145 else
146 mpImplFont->SetSymbolFlag( false );
147 }
148 }
149
IsSymbolFont() const150 bool Font::IsSymbolFont() const
151 {
152 return mpImplFont->IsSymbolFont();
153 }
154
SetSymbolFlag(bool bSymbol)155 void Font::SetSymbolFlag( bool bSymbol )
156 {
157 mpImplFont->SetSymbolFlag( bSymbol );
158
159 if ( IsSymbolFont() )
160 {
161 mpImplFont->SetCharSet( RTL_TEXTENCODING_SYMBOL );
162 }
163 else
164 {
165 if ( mpImplFont->GetCharSet() == RTL_TEXTENCODING_SYMBOL )
166 mpImplFont->SetCharSet( RTL_TEXTENCODING_DONTKNOW );
167 }
168 }
169
SetLanguageTag(const LanguageTag & rLanguageTag)170 void Font::SetLanguageTag( const LanguageTag& rLanguageTag )
171 {
172 if (const_cast<const ImplType&>(mpImplFont)->maLanguageTag != rLanguageTag)
173 mpImplFont->maLanguageTag = rLanguageTag;
174 }
175
SetCJKContextLanguageTag(const LanguageTag & rLanguageTag)176 void Font::SetCJKContextLanguageTag( const LanguageTag& rLanguageTag )
177 {
178 if (const_cast<const ImplType&>(mpImplFont)->maCJKLanguageTag != rLanguageTag)
179 mpImplFont->maCJKLanguageTag = rLanguageTag;
180 }
181
SetLanguage(LanguageType eLanguage)182 void Font::SetLanguage( LanguageType eLanguage )
183 {
184 if (const_cast<const ImplType&>(mpImplFont)->maLanguageTag.getLanguageType(false) != eLanguage)
185 mpImplFont->maLanguageTag.reset( eLanguage);
186 }
187
SetCJKContextLanguage(LanguageType eLanguage)188 void Font::SetCJKContextLanguage( LanguageType eLanguage )
189 {
190 if (const_cast<const ImplType&>(mpImplFont)->maCJKLanguageTag.getLanguageType(false) != eLanguage)
191 mpImplFont->maCJKLanguageTag.reset( eLanguage);
192 }
193
SetPitch(FontPitch ePitch)194 void Font::SetPitch( FontPitch ePitch )
195 {
196 if (const_cast<const ImplType&>(mpImplFont)->GetPitchNoAsk() != ePitch)
197 mpImplFont->SetPitch( ePitch );
198 }
199
SetOrientation(Degree10 nOrientation)200 void Font::SetOrientation( Degree10 nOrientation )
201 {
202 if (const_cast<const ImplType&>(mpImplFont)->mnOrientation != nOrientation)
203 mpImplFont->mnOrientation = nOrientation;
204 }
205
SetVertical(bool bVertical)206 void Font::SetVertical( bool bVertical )
207 {
208 if (const_cast<const ImplType&>(mpImplFont)->mbVertical != bVertical)
209 mpImplFont->mbVertical = bVertical;
210 }
211
SetKerning(FontKerning eKerning)212 void Font::SetKerning( FontKerning eKerning )
213 {
214 if (const_cast<const ImplType&>(mpImplFont)->meKerning != eKerning)
215 mpImplFont->meKerning = eKerning;
216 }
217
IsKerning() const218 bool Font::IsKerning() const
219 {
220 return mpImplFont->meKerning != FontKerning::NONE;
221 }
222
SetWeight(FontWeight eWeight)223 void Font::SetWeight( FontWeight eWeight )
224 {
225 if (const_cast<const ImplType&>(mpImplFont)->GetWeightNoAsk() != eWeight)
226 mpImplFont->SetWeight( eWeight );
227 }
228
SetWidthType(FontWidth eWidth)229 void Font::SetWidthType( FontWidth eWidth )
230 {
231 if (const_cast<const ImplType&>(mpImplFont)->GetWidthTypeNoAsk() != eWidth)
232 mpImplFont->SetWidthType( eWidth );
233 }
234
SetItalic(FontItalic eItalic)235 void Font::SetItalic( FontItalic eItalic )
236 {
237 if (const_cast<const ImplType&>(mpImplFont)->GetItalicNoAsk() != eItalic)
238 mpImplFont->SetItalic( eItalic );
239 }
240
SetOutline(bool bOutline)241 void Font::SetOutline( bool bOutline )
242 {
243 if (const_cast<const ImplType&>(mpImplFont)->mbOutline != bOutline)
244 mpImplFont->mbOutline = bOutline;
245 }
246
SetShadow(bool bShadow)247 void Font::SetShadow( bool bShadow )
248 {
249 if (const_cast<const ImplType&>(mpImplFont)->mbShadow != bShadow)
250 mpImplFont->mbShadow = bShadow;
251 }
252
SetUnderline(FontLineStyle eUnderline)253 void Font::SetUnderline( FontLineStyle eUnderline )
254 {
255 if (const_cast<const ImplType&>(mpImplFont)->meUnderline != eUnderline)
256 mpImplFont->meUnderline = eUnderline;
257 }
258
SetOverline(FontLineStyle eOverline)259 void Font::SetOverline( FontLineStyle eOverline )
260 {
261 if (const_cast<const ImplType&>(mpImplFont)->meOverline != eOverline)
262 mpImplFont->meOverline = eOverline;
263 }
264
SetStrikeout(FontStrikeout eStrikeout)265 void Font::SetStrikeout( FontStrikeout eStrikeout )
266 {
267 if (const_cast<const ImplType&>(mpImplFont)->meStrikeout != eStrikeout)
268 mpImplFont->meStrikeout = eStrikeout;
269 }
270
SetRelief(FontRelief eRelief)271 void Font::SetRelief( FontRelief eRelief )
272 {
273 if (const_cast<const ImplType&>(mpImplFont)->meRelief != eRelief)
274 mpImplFont->meRelief = eRelief;
275 }
276
SetEmphasisMark(FontEmphasisMark eEmphasisMark)277 void Font::SetEmphasisMark( FontEmphasisMark eEmphasisMark )
278 {
279 if (const_cast<const ImplType&>(mpImplFont)->meEmphasisMark != eEmphasisMark )
280 mpImplFont->meEmphasisMark = eEmphasisMark;
281 }
282
SetWordLineMode(bool bWordLine)283 void Font::SetWordLineMode( bool bWordLine )
284 {
285 if (const_cast<const ImplType&>(mpImplFont)->mbWordLine != bWordLine)
286 mpImplFont->mbWordLine = bWordLine;
287 }
288
operator =(const vcl::Font & rFont)289 Font& Font::operator=( const vcl::Font& rFont )
290 {
291 mpImplFont = rFont.mpImplFont;
292 return *this;
293 }
294
operator =(vcl::Font && rFont)295 Font& Font::operator=( vcl::Font&& rFont ) noexcept
296 {
297 mpImplFont = std::move(rFont.mpImplFont);
298 return *this;
299 }
300
operator ==(const vcl::Font & rFont) const301 bool Font::operator==( const vcl::Font& rFont ) const
302 {
303 return mpImplFont == rFont.mpImplFont;
304 }
305
Merge(const vcl::Font & rFont)306 void Font::Merge( const vcl::Font& rFont )
307 {
308 if ( !rFont.GetFamilyName().isEmpty() )
309 {
310 SetFamilyName( rFont.GetFamilyName() );
311 SetStyleName( rFont.GetStyleName() );
312 SetCharSet( GetCharSet() );
313 SetLanguageTag( rFont.GetLanguageTag() );
314 SetCJKContextLanguageTag( rFont.GetCJKContextLanguageTag() );
315 // don't use access methods here, might lead to AskConfig(), if DONTKNOW
316 SetFamily( rFont.mpImplFont->GetFamilyTypeNoAsk() );
317 SetPitch( rFont.mpImplFont->GetPitchNoAsk() );
318 }
319
320 // don't use access methods here, might lead to AskConfig(), if DONTKNOW
321 if ( rFont.mpImplFont->GetWeightNoAsk() != WEIGHT_DONTKNOW )
322 SetWeight( rFont.GetWeight() );
323 if ( rFont.mpImplFont->GetItalicNoAsk() != ITALIC_DONTKNOW )
324 SetItalic( rFont.GetItalic() );
325 if ( rFont.mpImplFont->GetWidthTypeNoAsk() != WIDTH_DONTKNOW )
326 SetWidthType( rFont.GetWidthType() );
327
328 if ( rFont.GetFontSize().Height() )
329 SetFontSize( rFont.GetFontSize() );
330 if ( rFont.GetUnderline() != LINESTYLE_DONTKNOW )
331 {
332 SetUnderline( rFont.GetUnderline() );
333 SetWordLineMode( rFont.IsWordLineMode() );
334 }
335 if ( rFont.GetOverline() != LINESTYLE_DONTKNOW )
336 {
337 SetOverline( rFont.GetOverline() );
338 SetWordLineMode( rFont.IsWordLineMode() );
339 }
340 if ( rFont.GetStrikeout() != STRIKEOUT_DONTKNOW )
341 {
342 SetStrikeout( rFont.GetStrikeout() );
343 SetWordLineMode( rFont.IsWordLineMode() );
344 }
345
346 // Defaults?
347 SetOrientation( rFont.GetOrientation() );
348 SetVertical( rFont.IsVertical() );
349 SetEmphasisMark( rFont.GetEmphasisMark() );
350 SetKerning( rFont.IsKerning() ? FontKerning::FontSpecific : FontKerning::NONE );
351 SetOutline( rFont.IsOutline() );
352 SetShadow( rFont.IsShadow() );
353 SetRelief( rFont.GetRelief() );
354 }
355
GetFontAttributes(FontAttributes & rAttrs) const356 void Font::GetFontAttributes( FontAttributes& rAttrs ) const
357 {
358 rAttrs.SetFamilyName( mpImplFont->GetFamilyName() );
359 rAttrs.SetStyleName( mpImplFont->maStyleName );
360 rAttrs.SetFamilyType( mpImplFont->GetFamilyTypeNoAsk() );
361 rAttrs.SetPitch( mpImplFont->GetPitchNoAsk() );
362 rAttrs.SetItalic( mpImplFont->GetItalicNoAsk() );
363 rAttrs.SetWeight( mpImplFont->GetWeightNoAsk() );
364 rAttrs.SetWidthType( WIDTH_DONTKNOW );
365 rAttrs.SetSymbolFlag( mpImplFont->GetCharSet() == RTL_TEXTENCODING_SYMBOL );
366 }
367
368 // tdf#127471 for corrections on EMF/WMF we need the AvgFontWidth in Windows-specific notation
GetOrCalculateAverageFontWidth() const369 tools::Long Font::GetOrCalculateAverageFontWidth() const
370 {
371 if(0 == mpImplFont->GetCalculatedAverageFontWidth())
372 {
373 // VirtualDevice is not thread safe
374 SolarMutexGuard aGuard;
375
376 // create unscaled copy of font (this), a VirtualDevice and set it there
377 vcl::Font aUnscaledFont(*this);
378 ScopedVclPtr<VirtualDevice> pTempVirtualDevice(VclPtr<VirtualDevice>::Create());
379 aUnscaledFont.SetAverageFontWidth(0);
380 pTempVirtualDevice->SetFont(aUnscaledFont);
381
382 #ifdef _WIN32
383 // on Windows systems use FontMetric to get/create AverageFontWidth from system
384 const FontMetric aMetric(pTempVirtualDevice->GetFontMetric());
385 const_cast<Font*>(this)->mpImplFont->SetCalculatedAverageFontWidth(aMetric.GetAverageFontWidth());
386 #else
387 // On non-Windows systems we need to calculate AvgFontWidth
388 // as close as possible (discussion see documentation in task),
389 // so calculate it. For discussion of method used, see task
390 // buffer measure string creation, will always use the same
391 static constexpr OUStringLiteral aMeasureString
392 = u"\u0020\u0021\u0022\u0023\u0024\u0025\u0026\u0027"
393 "\u0028\u0029\u002A\u002B\u002C\u002D\u002E\u002F"
394 "\u0030\u0031\u0032\u0033\u0034\u0035\u0036\u0037"
395 "\u0038\u0039\u003A\u003B\u003C\u003D\u003E\u003F"
396 "\u0040\u0041\u0042\u0043\u0044\u0045\u0046\u0047"
397 "\u0048\u0049\u004A\u004B\u004C\u004D\u004E\u004F"
398 "\u0050\u0051\u0052\u0053\u0054\u0055\u0056\u0057"
399 "\u0058\u0059\u005A\u005B\u005C\u005D\u005E\u005F"
400 "\u0060\u0061\u0062\u0063\u0064\u0065\u0066\u0067"
401 "\u0068\u0069\u006A\u006B\u006C\u006D\u006E\u006F"
402 "\u0070\u0071\u0072\u0073\u0074\u0075\u0076\u0077"
403 "\u0078\u0079\u007A\u007B\u007C\u007D\u007E";
404
405 const double fAverageFontWidth(
406 pTempVirtualDevice->GetTextWidth(aMeasureString) /
407 static_cast<double>(aMeasureString.getLength()));
408 const_cast<Font*>(this)->mpImplFont->SetCalculatedAverageFontWidth(basegfx::fround(fAverageFontWidth));
409 #endif
410 }
411
412 return mpImplFont->GetCalculatedAverageFontWidth();
413 }
414
ReadImplFont(SvStream & rIStm,ImplFont & rImplFont,tools::Long & rnNormedFontScaling)415 SvStream& ReadImplFont( SvStream& rIStm, ImplFont& rImplFont, tools::Long& rnNormedFontScaling )
416 {
417 VersionCompatRead aCompat( rIStm );
418 sal_uInt16 nTmp16(0);
419 sal_Int16 nTmps16(0);
420 bool bTmp(false);
421 sal_uInt8 nTmp8(0);
422
423 rImplFont.SetFamilyName( rIStm.ReadUniOrByteString(rIStm.GetStreamCharSet()) );
424 rImplFont.maStyleName = rIStm.ReadUniOrByteString(rIStm.GetStreamCharSet());
425 TypeSerializer aSerializer(rIStm);
426 aSerializer.readSize(rImplFont.maAverageFontSize);
427
428 rIStm.ReadUInt16( nTmp16 ); rImplFont.SetCharSet( static_cast<rtl_TextEncoding>(nTmp16) );
429 rIStm.ReadUInt16( nTmp16 ); rImplFont.SetFamilyType( static_cast<FontFamily>(nTmp16) );
430 rIStm.ReadUInt16( nTmp16 ); rImplFont.SetPitch( static_cast<FontPitch>(nTmp16) );
431 rIStm.ReadUInt16( nTmp16 ); rImplFont.SetWeight( static_cast<FontWeight>(nTmp16) );
432 rIStm.ReadUInt16( nTmp16 ); rImplFont.meUnderline = static_cast<FontLineStyle>(nTmp16);
433 rIStm.ReadUInt16( nTmp16 ); rImplFont.meStrikeout = static_cast<FontStrikeout>(nTmp16);
434 rIStm.ReadUInt16( nTmp16 ); rImplFont.SetItalic( static_cast<FontItalic>(nTmp16) );
435 rIStm.ReadUInt16( nTmp16 ); rImplFont.maLanguageTag.reset( LanguageType(nTmp16) );
436 rIStm.ReadUInt16( nTmp16 ); rImplFont.meWidthType = static_cast<FontWidth>(nTmp16);
437
438 rIStm.ReadInt16( nTmps16 ); rImplFont.mnOrientation = Degree10(nTmps16);
439
440 rIStm.ReadCharAsBool( bTmp ); rImplFont.mbWordLine = bTmp;
441 rIStm.ReadCharAsBool( bTmp ); rImplFont.mbOutline = bTmp;
442 rIStm.ReadCharAsBool( bTmp ); rImplFont.mbShadow = bTmp;
443 rIStm.ReadUChar( nTmp8 ); rImplFont.meKerning = static_cast<FontKerning>(nTmp8);
444
445 if( aCompat.GetVersion() >= 2 )
446 {
447 rIStm.ReadUChar( nTmp8 ); rImplFont.meRelief = static_cast<FontRelief>(nTmp8);
448 rIStm.ReadUInt16( nTmp16 ); rImplFont.maCJKLanguageTag.reset( LanguageType(nTmp16) );
449 rIStm.ReadCharAsBool( bTmp ); rImplFont.mbVertical = bTmp;
450 rIStm.ReadUInt16( nTmp16 ); rImplFont.meEmphasisMark = static_cast<FontEmphasisMark>(nTmp16);
451 }
452
453 if( aCompat.GetVersion() >= 3 )
454 {
455 rIStm.ReadUInt16( nTmp16 ); rImplFont.meOverline = static_cast<FontLineStyle>(nTmp16);
456 }
457
458 // tdf#127471 read NormedFontScaling
459 if( aCompat.GetVersion() >= 4 )
460 {
461 sal_Int32 nNormedFontScaling(0);
462 rIStm.ReadInt32(nNormedFontScaling);
463 rnNormedFontScaling = nNormedFontScaling;
464 }
465
466 // Relief
467 // CJKContextLanguage
468
469 return rIStm;
470 }
471
WriteImplFont(SvStream & rOStm,const ImplFont & rImplFont,const tools::Long & rnNormedFontScaling)472 SvStream& WriteImplFont( SvStream& rOStm, const ImplFont& rImplFont, const tools::Long& rnNormedFontScaling )
473 {
474 // tdf#127471 increase to version 4
475 VersionCompatWrite aCompat( rOStm, 4 );
476
477 TypeSerializer aSerializer(rOStm);
478 rOStm.WriteUniOrByteString( rImplFont.GetFamilyName(), rOStm.GetStreamCharSet() );
479 rOStm.WriteUniOrByteString( rImplFont.GetStyleName(), rOStm.GetStreamCharSet() );
480 aSerializer.writeSize(rImplFont.maAverageFontSize);
481
482 rOStm.WriteUInt16( GetStoreCharSet( rImplFont.GetCharSet() ) );
483 rOStm.WriteUInt16( rImplFont.GetFamilyTypeNoAsk() );
484 rOStm.WriteUInt16( rImplFont.GetPitchNoAsk() );
485 rOStm.WriteUInt16( rImplFont.GetWeightNoAsk() );
486 rOStm.WriteUInt16( rImplFont.meUnderline );
487 rOStm.WriteUInt16( rImplFont.meStrikeout );
488 rOStm.WriteUInt16( rImplFont.GetItalicNoAsk() );
489 rOStm.WriteUInt16( static_cast<sal_uInt16>(rImplFont.maLanguageTag.getLanguageType( false)) );
490 rOStm.WriteUInt16( rImplFont.GetWidthTypeNoAsk() );
491
492 rOStm.WriteInt16( rImplFont.mnOrientation.get() );
493
494 rOStm.WriteBool( rImplFont.mbWordLine );
495 rOStm.WriteBool( rImplFont.mbOutline );
496 rOStm.WriteBool( rImplFont.mbShadow );
497 rOStm.WriteUChar( static_cast<sal_uInt8>(rImplFont.meKerning) );
498
499 // new in version 2
500 rOStm.WriteUChar( static_cast<unsigned char>(rImplFont.meRelief) );
501 rOStm.WriteUInt16( static_cast<sal_uInt16>(rImplFont.maCJKLanguageTag.getLanguageType( false)) );
502 rOStm.WriteBool( rImplFont.mbVertical );
503 rOStm.WriteUInt16( static_cast<sal_uInt16>(rImplFont.meEmphasisMark) );
504
505 // new in version 3
506 rOStm.WriteUInt16( rImplFont.meOverline );
507
508 // new in version 4, NormedFontScaling
509 rOStm.WriteInt32(rnNormedFontScaling);
510
511 return rOStm;
512 }
513
ReadFont(SvStream & rIStm,vcl::Font & rFont)514 SvStream& ReadFont( SvStream& rIStm, vcl::Font& rFont )
515 {
516 // tdf#127471 try to read NormedFontScaling
517 tools::Long nNormedFontScaling(0);
518 SvStream& rRetval(ReadImplFont( rIStm, *rFont.mpImplFont, nNormedFontScaling ));
519
520 if (nNormedFontScaling > 0)
521 {
522 #ifdef _WIN32
523 // we run on windows and a NormedFontScaling was written
524 if(rFont.GetFontSize().getWidth() == nNormedFontScaling)
525 {
526 // the writing producer was running on a non-windows system, adapt to needed windows
527 // system-specific pre-multiply
528 const tools::Long nHeight(std::max<tools::Long>(rFont.GetFontSize().getHeight(), 0));
529 sal_uInt32 nScaledWidth(0);
530
531 if(nHeight > 0)
532 {
533 vcl::Font aUnscaledFont(rFont);
534 aUnscaledFont.SetAverageFontWidth(0);
535 const FontMetric aUnscaledFontMetric(Application::GetDefaultDevice()->GetFontMetric(aUnscaledFont));
536
537 if (nHeight > 0)
538 {
539 const double fScaleFactor(static_cast<double>(nNormedFontScaling) / static_cast<double>(nHeight));
540 nScaledWidth = basegfx::fround(static_cast<double>(aUnscaledFontMetric.GetAverageFontWidth()) * fScaleFactor);
541 }
542 }
543
544 rFont.SetAverageFontWidth(nScaledWidth);
545 }
546 else
547 {
548 // the writing producer was on a windows system, correct pre-multiplied value
549 // is already set, nothing to do. Ignore 2nd value. Here a check
550 // could be done if adapting the 2nd, NormedFontScaling value would be similar to
551 // the set value for plausibility reasons
552 }
553 #else
554 // we do not run on windows and a NormedFontScaling was written
555 if(rFont.GetFontSize().getWidth() == nNormedFontScaling)
556 {
557 // the writing producer was not on a windows system, correct value
558 // already set, nothing to do
559 }
560 else
561 {
562 // the writing producer was on a windows system, correct FontScaling.
563 // The correct non-pre-multiplied value is the 2nd one, use it
564 rFont.SetAverageFontWidth(nNormedFontScaling);
565 }
566 #endif
567 }
568
569 return rRetval;
570 }
571
WriteFont(SvStream & rOStm,const vcl::Font & rFont)572 SvStream& WriteFont( SvStream& rOStm, const vcl::Font& rFont )
573 {
574 // tdf#127471 prepare NormedFontScaling for additional export
575 tools::Long nNormedFontScaling(rFont.GetFontSize().getWidth());
576
577 // FontScaling usage at vcl-Font is detected by checking that FontWidth != 0
578 if (nNormedFontScaling > 0)
579 {
580 const tools::Long nHeight(std::max<tools::Long>(rFont.GetFontSize().getHeight(), 0));
581
582 // check for negative height
583 if(0 == nHeight)
584 {
585 nNormedFontScaling = 0;
586 }
587 else
588 {
589 #ifdef _WIN32
590 // for WIN32 the value is pre-multiplied with AverageFontWidth
591 // which makes it system-dependent. Turn that back to have the
592 // normed non-windows form of it for export as 2nd value
593 vcl::Font aUnscaledFont(rFont);
594 aUnscaledFont.SetAverageFontWidth(0);
595 const FontMetric aUnscaledFontMetric(
596 Application::GetDefaultDevice()->GetFontMetric(aUnscaledFont));
597
598 if (aUnscaledFontMetric.GetAverageFontWidth() > 0)
599 {
600 const double fScaleFactor(
601 static_cast<double>(nNormedFontScaling)
602 / static_cast<double>(aUnscaledFontMetric.GetAverageFontWidth()));
603 nNormedFontScaling = static_cast<tools::Long>(fScaleFactor * nHeight);
604 }
605 #endif
606 }
607 }
608
609 return WriteImplFont( rOStm, *rFont.mpImplFont, nNormedFontScaling );
610 }
611
612 namespace
613 {
identifyTrueTypeFont(const void * i_pBuffer,sal_uInt32 i_nSize,Font & o_rResult)614 bool identifyTrueTypeFont( const void* i_pBuffer, sal_uInt32 i_nSize, Font& o_rResult )
615 {
616 bool bResult = false;
617 TrueTypeFont* pTTF = nullptr;
618 if( OpenTTFontBuffer( i_pBuffer, i_nSize, 0, &pTTF ) == SFErrCodes::Ok )
619 {
620 TTGlobalFontInfo aInfo;
621 GetTTGlobalFontInfo( pTTF, &aInfo );
622 // most importantly: the family name
623 if( aInfo.ufamily )
624 o_rResult.SetFamilyName( OUString(aInfo.ufamily) );
625 else if( aInfo.family )
626 o_rResult.SetFamilyName( OStringToOUString( aInfo.family, RTL_TEXTENCODING_ASCII_US ) );
627 // set weight
628 if( aInfo.weight )
629 {
630 if( aInfo.weight < FW_EXTRALIGHT )
631 o_rResult.SetWeight( WEIGHT_THIN );
632 else if( aInfo.weight < FW_LIGHT )
633 o_rResult.SetWeight( WEIGHT_ULTRALIGHT );
634 else if( aInfo.weight < FW_NORMAL )
635 o_rResult.SetWeight( WEIGHT_LIGHT );
636 else if( aInfo.weight < FW_MEDIUM )
637 o_rResult.SetWeight( WEIGHT_NORMAL );
638 else if( aInfo.weight < FW_SEMIBOLD )
639 o_rResult.SetWeight( WEIGHT_MEDIUM );
640 else if( aInfo.weight < FW_BOLD )
641 o_rResult.SetWeight( WEIGHT_SEMIBOLD );
642 else if( aInfo.weight < FW_EXTRABOLD )
643 o_rResult.SetWeight( WEIGHT_BOLD );
644 else if( aInfo.weight < FW_BLACK )
645 o_rResult.SetWeight( WEIGHT_ULTRABOLD );
646 else
647 o_rResult.SetWeight( WEIGHT_BLACK );
648 }
649 else
650 o_rResult.SetWeight( (aInfo.macStyle & 1) ? WEIGHT_BOLD : WEIGHT_NORMAL );
651 // set width
652 if( aInfo.width )
653 {
654 if( aInfo.width == FWIDTH_ULTRA_CONDENSED )
655 o_rResult.SetAverageFontWidth( WIDTH_ULTRA_CONDENSED );
656 else if( aInfo.width == FWIDTH_EXTRA_CONDENSED )
657 o_rResult.SetAverageFontWidth( WIDTH_EXTRA_CONDENSED );
658 else if( aInfo.width == FWIDTH_CONDENSED )
659 o_rResult.SetAverageFontWidth( WIDTH_CONDENSED );
660 else if( aInfo.width == FWIDTH_SEMI_CONDENSED )
661 o_rResult.SetAverageFontWidth( WIDTH_SEMI_CONDENSED );
662 else if( aInfo.width == FWIDTH_NORMAL )
663 o_rResult.SetAverageFontWidth( WIDTH_NORMAL );
664 else if( aInfo.width == FWIDTH_SEMI_EXPANDED )
665 o_rResult.SetAverageFontWidth( WIDTH_SEMI_EXPANDED );
666 else if( aInfo.width == FWIDTH_EXPANDED )
667 o_rResult.SetAverageFontWidth( WIDTH_EXPANDED );
668 else if( aInfo.width == FWIDTH_EXTRA_EXPANDED )
669 o_rResult.SetAverageFontWidth( WIDTH_EXTRA_EXPANDED );
670 else if( aInfo.width >= FWIDTH_ULTRA_EXPANDED )
671 o_rResult.SetAverageFontWidth( WIDTH_ULTRA_EXPANDED );
672 }
673 // set italic
674 o_rResult.SetItalic( (aInfo.italicAngle != 0) ? ITALIC_NORMAL : ITALIC_NONE );
675
676 // set pitch
677 o_rResult.SetPitch( (aInfo.pitch == 0) ? PITCH_VARIABLE : PITCH_FIXED );
678
679 // set style name
680 if( aInfo.usubfamily )
681 o_rResult.SetStyleName( OUString( aInfo.usubfamily ) );
682 else if( aInfo.subfamily )
683 o_rResult.SetStyleName( OUString::createFromAscii( aInfo.subfamily ) );
684
685 // cleanup
686 CloseTTFont( pTTF );
687 // success
688 bResult = true;
689 }
690 return bResult;
691 }
692
693 struct WeightSearchEntry
694 {
695 const char* string;
696 int string_len;
697 FontWeight weight;
698
operator <__anon8415ccdf0211::WeightSearchEntry699 bool operator<( const WeightSearchEntry& rRight ) const
700 {
701 return rtl_str_compareIgnoreAsciiCase_WithLength( string, string_len, rRight.string, rRight.string_len ) < 0;
702 }
703 }
704 const weight_table[] =
705 {
706 { "black", 5, WEIGHT_BLACK },
707 { "bold", 4, WEIGHT_BOLD },
708 { "book", 4, WEIGHT_LIGHT },
709 { "demi", 4, WEIGHT_SEMIBOLD },
710 { "heavy", 5, WEIGHT_BLACK },
711 { "light", 5, WEIGHT_LIGHT },
712 { "medium", 6, WEIGHT_MEDIUM },
713 { "regular", 7, WEIGHT_NORMAL },
714 { "super", 5, WEIGHT_ULTRABOLD },
715 { "thin", 4, WEIGHT_THIN }
716 };
717
identifyType1Font(const char * i_pBuffer,sal_uInt32 i_nSize,Font & o_rResult)718 bool identifyType1Font( const char* i_pBuffer, sal_uInt32 i_nSize, Font& o_rResult )
719 {
720 // might be a type1, find eexec
721 const char* pStream = i_pBuffer;
722 const char* const pExec = "eexec";
723 const char* pExecPos = std::search( pStream, pStream+i_nSize, pExec, pExec+5 );
724 if( pExecPos != pStream+i_nSize)
725 {
726 // find /FamilyName entry
727 static const char* const pFam = "/FamilyName";
728 const char* pFamPos = std::search( pStream, pExecPos, pFam, pFam+11 );
729 if( pFamPos != pExecPos )
730 {
731 // extract the string value behind /FamilyName
732 const char* pOpen = pFamPos+11;
733 while( pOpen < pExecPos && *pOpen != '(' )
734 pOpen++;
735 const char* pClose = pOpen;
736 while( pClose < pExecPos && *pClose != ')' )
737 pClose++;
738 if( pClose - pOpen > 1 )
739 {
740 o_rResult.SetFamilyName( OStringToOUString( std::string_view( pOpen+1, pClose-pOpen-1 ), RTL_TEXTENCODING_ASCII_US ) );
741 }
742 }
743
744 // parse /ItalicAngle
745 static const char* const pItalic = "/ItalicAngle";
746 const char* pItalicPos = std::search( pStream, pExecPos, pItalic, pItalic+12 );
747 if( pItalicPos != pExecPos )
748 {
749 const char* pItalicEnd = pItalicPos + 12;
750 auto nItalic = rtl_str_toInt64_WithLength(pItalicEnd, 10, pExecPos - pItalicEnd);
751 o_rResult.SetItalic( (nItalic != 0) ? ITALIC_NORMAL : ITALIC_NONE );
752 }
753
754 // parse /Weight
755 static const char* const pWeight = "/Weight";
756 const char* pWeightPos = std::search( pStream, pExecPos, pWeight, pWeight+7 );
757 if( pWeightPos != pExecPos )
758 {
759 // extract the string value behind /Weight
760 const char* pOpen = pWeightPos+7;
761 while( pOpen < pExecPos && *pOpen != '(' )
762 pOpen++;
763 const char* pClose = pOpen;
764 while( pClose < pExecPos && *pClose != ')' )
765 pClose++;
766 if( pClose - pOpen > 1 )
767 {
768 WeightSearchEntry aEnt;
769 aEnt.string = pOpen+1;
770 aEnt.string_len = (pClose-pOpen)-1;
771 aEnt.weight = WEIGHT_NORMAL;
772 WeightSearchEntry const * pFound = std::lower_bound( std::begin(weight_table), std::end(weight_table), aEnt );
773 if( pFound != std::end(weight_table) &&
774 rtl_str_compareIgnoreAsciiCase_WithLength( pFound->string, pFound->string_len, aEnt.string, aEnt.string_len) == 0 )
775 o_rResult.SetWeight( pFound->weight );
776 }
777 }
778
779 // parse isFixedPitch
780 static const char* const pFixed = "/isFixedPitch";
781 const char* pFixedPos = std::search( pStream, pExecPos, pFixed, pFixed+13 );
782 if( pFixedPos != pExecPos )
783 {
784 // skip whitespace
785 while( pFixedPos < pExecPos-4 &&
786 ( *pFixedPos == ' ' ||
787 *pFixedPos == '\t' ||
788 *pFixedPos == '\r' ||
789 *pFixedPos == '\n' ) )
790 {
791 pFixedPos++;
792 }
793 // find "true" value
794 if( rtl_str_compareIgnoreAsciiCase_WithLength( pFixedPos, 4, "true", 4 ) == 0 )
795 o_rResult.SetPitch( PITCH_FIXED );
796 else
797 o_rResult.SetPitch( PITCH_VARIABLE );
798 }
799 }
800 return false;
801 }
802 }
803
identifyFont(const void * i_pBuffer,sal_uInt32 i_nSize)804 Font Font::identifyFont( const void* i_pBuffer, sal_uInt32 i_nSize )
805 {
806 Font aResult;
807 if( ! identifyTrueTypeFont( i_pBuffer, i_nSize, aResult ) )
808 {
809 const char* pStream = static_cast<const char*>(i_pBuffer);
810 if( pStream && i_nSize > 100 &&
811 *pStream == '%' && pStream[1] == '!' )
812 {
813 identifyType1Font( pStream, i_nSize, aResult );
814 }
815 }
816
817 return aResult;
818 }
819
820 // The inlines from the font.hxx header are now instantiated for pImpl-ification
GetColor() const821 const Color& Font::GetColor() const { return mpImplFont->maColor; }
GetFillColor() const822 const Color& Font::GetFillColor() const { return mpImplFont->maFillColor; }
IsTransparent() const823 bool Font::IsTransparent() const { return mpImplFont->mbTransparent; }
824
GetAlignment() const825 FontAlign Font::GetAlignment() const { return mpImplFont->GetAlignment(); }
826
GetFamilyName() const827 const OUString& Font::GetFamilyName() const { return mpImplFont->GetFamilyName(); }
GetStyleName() const828 const OUString& Font::GetStyleName() const { return mpImplFont->maStyleName; }
829
GetFontSize() const830 const Size& Font::GetFontSize() const { return mpImplFont->GetFontSize(); }
SetFontHeight(tools::Long nHeight)831 void Font::SetFontHeight( tools::Long nHeight ) { SetFontSize( Size( mpImplFont->GetFontSize().Width(), nHeight ) ); }
GetFontHeight() const832 tools::Long Font::GetFontHeight() const { return mpImplFont->GetFontSize().Height(); }
SetAverageFontWidth(tools::Long nWidth)833 void Font::SetAverageFontWidth( tools::Long nWidth ) { SetFontSize( Size( nWidth, mpImplFont->GetFontSize().Height() ) ); }
GetAverageFontWidth() const834 tools::Long Font::GetAverageFontWidth() const { return mpImplFont->GetFontSize().Width(); }
835
GetCharSet() const836 rtl_TextEncoding Font::GetCharSet() const { return mpImplFont->GetCharSet(); }
837
GetLanguageTag() const838 const LanguageTag& Font::GetLanguageTag() const { return mpImplFont->maLanguageTag; }
GetCJKContextLanguageTag() const839 const LanguageTag& Font::GetCJKContextLanguageTag() const { return mpImplFont->maCJKLanguageTag; }
GetLanguage() const840 LanguageType Font::GetLanguage() const { return mpImplFont->maLanguageTag.getLanguageType( false); }
GetCJKContextLanguage() const841 LanguageType Font::GetCJKContextLanguage() const { return mpImplFont->maCJKLanguageTag.getLanguageType( false); }
842
GetOrientation() const843 Degree10 Font::GetOrientation() const { return mpImplFont->mnOrientation; }
IsVertical() const844 bool Font::IsVertical() const { return mpImplFont->mbVertical; }
GetKerning() const845 FontKerning Font::GetKerning() const { return mpImplFont->meKerning; }
846
GetPitch()847 FontPitch Font::GetPitch() { return mpImplFont->GetPitch(); }
GetWeight()848 FontWeight Font::GetWeight() { return mpImplFont->GetWeight(); }
GetWidthType()849 FontWidth Font::GetWidthType() { return mpImplFont->GetWidthType(); }
GetItalic()850 FontItalic Font::GetItalic() { return mpImplFont->GetItalic(); }
GetFamilyType()851 FontFamily Font::GetFamilyType() { return mpImplFont->GetFamilyType(); }
852
GetPitch() const853 FontPitch Font::GetPitch() const { return mpImplFont->GetPitchNoAsk(); }
GetWeight() const854 FontWeight Font::GetWeight() const { return mpImplFont->GetWeightNoAsk(); }
GetWidthType() const855 FontWidth Font::GetWidthType() const { return mpImplFont->GetWidthTypeNoAsk(); }
GetItalic() const856 FontItalic Font::GetItalic() const { return mpImplFont->GetItalicNoAsk(); }
GetFamilyType() const857 FontFamily Font::GetFamilyType() const { return mpImplFont->GetFamilyTypeNoAsk(); }
858
GetQuality() const859 int Font::GetQuality() const { return mpImplFont->GetQuality(); }
SetQuality(int nQuality)860 void Font::SetQuality( int nQuality ) { mpImplFont->SetQuality( nQuality ); }
IncreaseQualityBy(int nQualityAmount)861 void Font::IncreaseQualityBy( int nQualityAmount ) { mpImplFont->IncreaseQualityBy( nQualityAmount ); }
DecreaseQualityBy(int nQualityAmount)862 void Font::DecreaseQualityBy( int nQualityAmount ) { mpImplFont->DecreaseQualityBy( nQualityAmount ); }
863
IsOutline() const864 bool Font::IsOutline() const { return mpImplFont->mbOutline; }
IsShadow() const865 bool Font::IsShadow() const { return mpImplFont->mbShadow; }
GetRelief() const866 FontRelief Font::GetRelief() const { return mpImplFont->meRelief; }
GetUnderline() const867 FontLineStyle Font::GetUnderline() const { return mpImplFont->meUnderline; }
GetOverline() const868 FontLineStyle Font::GetOverline() const { return mpImplFont->meOverline; }
GetStrikeout() const869 FontStrikeout Font::GetStrikeout() const { return mpImplFont->meStrikeout; }
GetEmphasisMark() const870 FontEmphasisMark Font::GetEmphasisMark() const { return mpImplFont->meEmphasisMark; }
IsWordLineMode() const871 bool Font::IsWordLineMode() const { return mpImplFont->mbWordLine; }
IsSameInstance(const vcl::Font & rFont) const872 bool Font::IsSameInstance( const vcl::Font& rFont ) const { return (mpImplFont == rFont.mpImplFont); }
873
874
ImplFont()875 ImplFont::ImplFont() :
876 meWeight( WEIGHT_DONTKNOW ),
877 meFamily( FAMILY_DONTKNOW ),
878 mePitch( PITCH_DONTKNOW ),
879 meWidthType( WIDTH_DONTKNOW ),
880 meItalic( ITALIC_NONE ),
881 meAlign( ALIGN_TOP ),
882 meUnderline( LINESTYLE_NONE ),
883 meOverline( LINESTYLE_NONE ),
884 meStrikeout( STRIKEOUT_NONE ),
885 meRelief( FontRelief::NONE ),
886 meEmphasisMark( FontEmphasisMark::NONE ),
887 meKerning( FontKerning::FontSpecific ),
888 meCharSet( RTL_TEXTENCODING_DONTKNOW ),
889 maLanguageTag( LANGUAGE_DONTKNOW ),
890 maCJKLanguageTag( LANGUAGE_DONTKNOW ),
891 mbSymbolFlag( false ),
892 mbOutline( false ),
893 mbConfigLookup( false ),
894 mbShadow( false ),
895 mbVertical( false ),
896 mbTransparent( true ),
897 maColor( COL_TRANSPARENT ),
898 maFillColor( COL_TRANSPARENT ),
899 mbWordLine( false ),
900 mnOrientation( 0 ),
901 mnQuality( 0 ),
902 mnCalculatedAverageFontWidth( 0 )
903 {}
904
ImplFont(const ImplFont & rImplFont)905 ImplFont::ImplFont( const ImplFont& rImplFont ) :
906 maFamilyName( rImplFont.maFamilyName ),
907 maStyleName( rImplFont.maStyleName ),
908 meWeight( rImplFont.meWeight ),
909 meFamily( rImplFont.meFamily ),
910 mePitch( rImplFont.mePitch ),
911 meWidthType( rImplFont.meWidthType ),
912 meItalic( rImplFont.meItalic ),
913 meAlign( rImplFont.meAlign ),
914 meUnderline( rImplFont.meUnderline ),
915 meOverline( rImplFont.meOverline ),
916 meStrikeout( rImplFont.meStrikeout ),
917 meRelief( rImplFont.meRelief ),
918 meEmphasisMark( rImplFont.meEmphasisMark ),
919 meKerning( rImplFont.meKerning ),
920 maAverageFontSize( rImplFont.maAverageFontSize ),
921 meCharSet( rImplFont.meCharSet ),
922 maLanguageTag( rImplFont.maLanguageTag ),
923 maCJKLanguageTag( rImplFont.maCJKLanguageTag ),
924 mbSymbolFlag( rImplFont.mbSymbolFlag ),
925 mbOutline( rImplFont.mbOutline ),
926 mbConfigLookup( rImplFont.mbConfigLookup ),
927 mbShadow( rImplFont.mbShadow ),
928 mbVertical( rImplFont.mbVertical ),
929 mbTransparent( rImplFont.mbTransparent ),
930 maColor( rImplFont.maColor ),
931 maFillColor( rImplFont.maFillColor ),
932 mbWordLine( rImplFont.mbWordLine ),
933 mnOrientation( rImplFont.mnOrientation ),
934 mnQuality( rImplFont.mnQuality ),
935 mnCalculatedAverageFontWidth( rImplFont.mnCalculatedAverageFontWidth )
936 {}
937
operator ==(const ImplFont & rOther) const938 bool ImplFont::operator==( const ImplFont& rOther ) const
939 {
940 // equality tests split up for easier debugging
941 if( (meWeight != rOther.meWeight)
942 || (meItalic != rOther.meItalic)
943 || (meFamily != rOther.meFamily)
944 || (mePitch != rOther.mePitch) )
945 return false;
946
947 if( (meCharSet != rOther.meCharSet)
948 || (maLanguageTag != rOther.maLanguageTag)
949 || (maCJKLanguageTag != rOther.maCJKLanguageTag)
950 || (meAlign != rOther.meAlign) )
951 return false;
952
953 if( (maAverageFontSize != rOther.maAverageFontSize)
954 || (mnOrientation != rOther.mnOrientation)
955 || (mbVertical != rOther.mbVertical) )
956 return false;
957
958 if( (maFamilyName != rOther.maFamilyName)
959 || (maStyleName != rOther.maStyleName) )
960 return false;
961
962 if( (maColor != rOther.maColor)
963 || (maFillColor != rOther.maFillColor) )
964 return false;
965
966 if( (meUnderline != rOther.meUnderline)
967 || (meOverline != rOther.meOverline)
968 || (meStrikeout != rOther.meStrikeout)
969 || (meRelief != rOther.meRelief)
970 || (meEmphasisMark != rOther.meEmphasisMark)
971 || (mbWordLine != rOther.mbWordLine)
972 || (mbOutline != rOther.mbOutline)
973 || (mbShadow != rOther.mbShadow)
974 || (meKerning != rOther.meKerning)
975 || (mbTransparent != rOther.mbTransparent) )
976 return false;
977
978 return true;
979 }
980
AskConfig()981 void ImplFont::AskConfig()
982 {
983 if( mbConfigLookup )
984 return;
985
986 mbConfigLookup = true;
987
988 // prepare the FontSubst configuration lookup
989 const utl::FontSubstConfiguration& rFontSubst = utl::FontSubstConfiguration::get();
990
991 OUString aShortName;
992 OUString aFamilyName;
993 ImplFontAttrs nType = ImplFontAttrs::None;
994 FontWeight eWeight = WEIGHT_DONTKNOW;
995 FontWidth eWidthType = WIDTH_DONTKNOW;
996 OUString aMapName = GetEnglishSearchFontName( maFamilyName );
997
998 utl::FontSubstConfiguration::getMapName( aMapName,
999 aShortName, aFamilyName, eWeight, eWidthType, nType );
1000
1001 // lookup the font name in the configuration
1002 const utl::FontNameAttr* pFontAttr = rFontSubst.getSubstInfo( aMapName );
1003
1004 // if the direct lookup failed try again with an alias name
1005 if ( !pFontAttr && (aShortName != aMapName) )
1006 pFontAttr = rFontSubst.getSubstInfo( aShortName );
1007
1008 if( pFontAttr )
1009 {
1010 // the font was found in the configuration
1011 if( meFamily == FAMILY_DONTKNOW )
1012 {
1013 if ( pFontAttr->Type & ImplFontAttrs::Serif )
1014 meFamily = FAMILY_ROMAN;
1015 else if ( pFontAttr->Type & ImplFontAttrs::SansSerif )
1016 meFamily = FAMILY_SWISS;
1017 else if ( pFontAttr->Type & ImplFontAttrs::Typewriter )
1018 meFamily = FAMILY_MODERN;
1019 else if ( pFontAttr->Type & ImplFontAttrs::Italic )
1020 meFamily = FAMILY_SCRIPT;
1021 else if ( pFontAttr->Type & ImplFontAttrs::Decorative )
1022 meFamily = FAMILY_DECORATIVE;
1023 }
1024
1025 if( mePitch == PITCH_DONTKNOW )
1026 {
1027 if ( pFontAttr->Type & ImplFontAttrs::Fixed )
1028 mePitch = PITCH_FIXED;
1029 }
1030 }
1031
1032 // if some attributes are still unknown then use the FontSubst magic
1033 if( meFamily == FAMILY_DONTKNOW )
1034 {
1035 if( nType & ImplFontAttrs::Serif )
1036 meFamily = FAMILY_ROMAN;
1037 else if( nType & ImplFontAttrs::SansSerif )
1038 meFamily = FAMILY_SWISS;
1039 else if( nType & ImplFontAttrs::Typewriter )
1040 meFamily = FAMILY_MODERN;
1041 else if( nType & ImplFontAttrs::Italic )
1042 meFamily = FAMILY_SCRIPT;
1043 else if( nType & ImplFontAttrs::Decorative )
1044 meFamily = FAMILY_DECORATIVE;
1045 }
1046
1047 if( GetWeight() == WEIGHT_DONTKNOW )
1048 SetWeight( eWeight );
1049 if( meWidthType == WIDTH_DONTKNOW )
1050 meWidthType = eWidthType;
1051 }
1052
1053 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
1054