1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
3 * This file is part of the LibreOffice project.
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/.
9 * This file incorporates work covered by the following license notice:
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 .
20 #include <sal/macros.h>
21 #include <tools/stream.hxx>
22 #include <tools/vcompat.hxx>
23 #include <tools/gen.hxx>
24 #include <unotools/fontcfg.hxx>
25 #include <unotools/fontdefs.hxx>
27 #include <vcl/font.hxx>
29 #include "impfont.hxx"
30 #include "fontinstance.hxx"
31 #include "fontattributes.hxx"
36 #include <rtl/instance.hxx>
42 struct theGlobalDefault
:
43 public rtl::Static
< Font::ImplType
, theGlobalDefault
> {};
46 Font::Font() : mpImplFont(theGlobalDefault::get())
50 Font::Font( const vcl::Font
& rFont
) : mpImplFont( rFont
.mpImplFont
)
54 Font::Font( vcl::Font
&& rFont
) : mpImplFont( std::move(rFont
.mpImplFont
) )
58 Font::Font( const OUString
& rFamilyName
, const Size
& rSize
) : mpImplFont()
60 mpImplFont
->SetFamilyName( rFamilyName
);
61 mpImplFont
->SetFontSize( rSize
);
64 Font::Font( const OUString
& rFamilyName
, const OUString
& rStyleName
, const Size
& rSize
) : mpImplFont()
66 mpImplFont
->SetFamilyName( rFamilyName
);
67 mpImplFont
->SetStyleName( rStyleName
);
68 mpImplFont
->SetFontSize( rSize
);
71 Font::Font( FontFamily eFamily
, const Size
& rSize
) : mpImplFont()
73 mpImplFont
->SetFamilyType( eFamily
);
74 mpImplFont
->SetFontSize( rSize
);
81 void Font::SetColor( const Color
& rColor
)
83 if (const_cast<const ImplType
&>(mpImplFont
)->maColor
!= rColor
)
85 mpImplFont
->maColor
= rColor
;
89 void Font::SetFillColor( const Color
& rColor
)
91 mpImplFont
->maFillColor
= rColor
;
92 if ( rColor
.GetTransparency() )
93 mpImplFont
->mbTransparent
= true;
96 void Font::SetTransparent( bool bTransparent
)
98 if (const_cast<const ImplType
&>(mpImplFont
)->mbTransparent
!= bTransparent
)
99 mpImplFont
->mbTransparent
= bTransparent
;
102 void Font::SetAlignment( FontAlign eAlign
)
104 if (const_cast<const ImplType
&>(mpImplFont
)->meAlign
!= eAlign
)
105 mpImplFont
->SetAlignment(eAlign
);
108 void Font::SetFamilyName( const OUString
& rFamilyName
)
110 mpImplFont
->SetFamilyName( rFamilyName
);
113 void Font::SetStyleName( const OUString
& rStyleName
)
115 mpImplFont
->maStyleName
= rStyleName
;
118 void Font::SetFontSize( const Size
& rSize
)
120 if (const_cast<const ImplType
&>(mpImplFont
)->GetFontSize() != rSize
)
121 mpImplFont
->SetFontSize( rSize
);
124 void Font::SetFamily( FontFamily eFamily
)
126 if (const_cast<const ImplType
&>(mpImplFont
)->GetFamilyTypeNoAsk() != eFamily
)
127 mpImplFont
->SetFamilyType( eFamily
);
130 void Font::SetCharSet( rtl_TextEncoding eCharSet
)
132 if (const_cast<const ImplType
&>(mpImplFont
)->GetCharSet() != eCharSet
)
134 mpImplFont
->SetCharSet( eCharSet
);
136 if ( eCharSet
== RTL_TEXTENCODING_SYMBOL
)
137 mpImplFont
->SetSymbolFlag( true );
139 mpImplFont
->SetSymbolFlag( false );
143 bool Font::IsSymbolFont() const
145 return mpImplFont
->IsSymbolFont();
148 void Font::SetSymbolFlag( bool bSymbol
)
150 mpImplFont
->SetSymbolFlag( bSymbol
);
152 if ( IsSymbolFont() )
154 mpImplFont
->SetCharSet( RTL_TEXTENCODING_SYMBOL
);
158 if ( mpImplFont
->GetCharSet() == RTL_TEXTENCODING_SYMBOL
)
159 mpImplFont
->SetCharSet( RTL_TEXTENCODING_DONTKNOW
);
163 void Font::SetLanguageTag( const LanguageTag
& rLanguageTag
)
165 if (const_cast<const ImplType
&>(mpImplFont
)->maLanguageTag
!= rLanguageTag
)
166 mpImplFont
->maLanguageTag
= rLanguageTag
;
169 void Font::SetCJKContextLanguageTag( const LanguageTag
& rLanguageTag
)
171 if (const_cast<const ImplType
&>(mpImplFont
)->maCJKLanguageTag
!= rLanguageTag
)
172 mpImplFont
->maCJKLanguageTag
= rLanguageTag
;
175 void Font::SetLanguage( LanguageType eLanguage
)
177 if (const_cast<const ImplType
&>(mpImplFont
)->maLanguageTag
.getLanguageType(false) != eLanguage
)
178 mpImplFont
->maLanguageTag
.reset( eLanguage
);
181 void Font::SetCJKContextLanguage( LanguageType eLanguage
)
183 if (const_cast<const ImplType
&>(mpImplFont
)->maCJKLanguageTag
.getLanguageType(false) != eLanguage
)
184 mpImplFont
->maCJKLanguageTag
.reset( eLanguage
);
187 void Font::SetPitch( FontPitch ePitch
)
189 if (const_cast<const ImplType
&>(mpImplFont
)->GetPitchNoAsk() != ePitch
)
190 mpImplFont
->SetPitch( ePitch
);
193 void Font::SetOrientation( short nOrientation
)
195 if (const_cast<const ImplType
&>(mpImplFont
)->mnOrientation
!= nOrientation
)
196 mpImplFont
->mnOrientation
= nOrientation
;
199 void Font::SetVertical( bool bVertical
)
201 if (const_cast<const ImplType
&>(mpImplFont
)->mbVertical
!= bVertical
)
202 mpImplFont
->mbVertical
= bVertical
;
205 void Font::SetKerning( FontKerning eKerning
)
207 if (const_cast<const ImplType
&>(mpImplFont
)->meKerning
!= eKerning
)
208 mpImplFont
->meKerning
= eKerning
;
211 bool Font::IsKerning() const
213 return !(mpImplFont
->meKerning
== FontKerning::NONE
);
216 void Font::SetWeight( FontWeight eWeight
)
218 if (const_cast<const ImplType
&>(mpImplFont
)->GetWeightNoAsk() != eWeight
)
219 mpImplFont
->SetWeight( eWeight
);
222 void Font::SetWidthType( FontWidth eWidth
)
224 if (const_cast<const ImplType
&>(mpImplFont
)->GetWidthTypeNoAsk() != eWidth
)
225 mpImplFont
->SetWidthType( eWidth
);
228 void Font::SetItalic( FontItalic eItalic
)
230 if (const_cast<const ImplType
&>(mpImplFont
)->GetItalicNoAsk() != eItalic
)
231 mpImplFont
->SetItalic( eItalic
);
234 void Font::SetOutline( bool bOutline
)
236 if (const_cast<const ImplType
&>(mpImplFont
)->mbOutline
!= bOutline
)
237 mpImplFont
->mbOutline
= bOutline
;
240 void Font::SetShadow( bool bShadow
)
242 if (const_cast<const ImplType
&>(mpImplFont
)->mbShadow
!= bShadow
)
243 mpImplFont
->mbShadow
= bShadow
;
246 void Font::SetUnderline( FontLineStyle eUnderline
)
248 if (const_cast<const ImplType
&>(mpImplFont
)->meUnderline
!= eUnderline
)
249 mpImplFont
->meUnderline
= eUnderline
;
252 void Font::SetOverline( FontLineStyle eOverline
)
254 if (const_cast<const ImplType
&>(mpImplFont
)->meOverline
!= eOverline
)
255 mpImplFont
->meOverline
= eOverline
;
258 void Font::SetStrikeout( FontStrikeout eStrikeout
)
260 if (const_cast<const ImplType
&>(mpImplFont
)->meStrikeout
!= eStrikeout
)
261 mpImplFont
->meStrikeout
= eStrikeout
;
264 void Font::SetRelief( FontRelief eRelief
)
266 if (const_cast<const ImplType
&>(mpImplFont
)->meRelief
!= eRelief
)
267 mpImplFont
->meRelief
= eRelief
;
270 void Font::SetEmphasisMark( FontEmphasisMark eEmphasisMark
)
272 if (const_cast<const ImplType
&>(mpImplFont
)->meEmphasisMark
!= eEmphasisMark
)
273 mpImplFont
->meEmphasisMark
= eEmphasisMark
;
276 void Font::SetWordLineMode( bool bWordLine
)
278 if (const_cast<const ImplType
&>(mpImplFont
)->mbWordLine
!= bWordLine
)
279 mpImplFont
->mbWordLine
= bWordLine
;
282 Font
& Font::operator=( const vcl::Font
& rFont
)
284 mpImplFont
= rFont
.mpImplFont
;
288 Font
& Font::operator=( vcl::Font
&& rFont
)
290 mpImplFont
= std::move(rFont
.mpImplFont
);
294 bool Font::operator==( const vcl::Font
& rFont
) const
296 return mpImplFont
== rFont
.mpImplFont
;
299 void Font::Merge( const vcl::Font
& rFont
)
301 if ( !rFont
.GetFamilyName().isEmpty() )
303 SetFamilyName( rFont
.GetFamilyName() );
304 SetStyleName( rFont
.GetStyleName() );
305 SetCharSet( GetCharSet() );
306 SetLanguageTag( rFont
.GetLanguageTag() );
307 SetCJKContextLanguageTag( rFont
.GetCJKContextLanguageTag() );
308 // don't use access methods here, might lead to AskConfig(), if DONTKNOW
309 SetFamily( rFont
.mpImplFont
->GetFamilyTypeNoAsk() );
310 SetPitch( rFont
.mpImplFont
->GetPitchNoAsk() );
313 // don't use access methods here, might lead to AskConfig(), if DONTKNOW
314 if ( rFont
.mpImplFont
->GetWeightNoAsk() != WEIGHT_DONTKNOW
)
315 SetWeight( rFont
.GetWeight() );
316 if ( rFont
.mpImplFont
->GetItalicNoAsk() != ITALIC_DONTKNOW
)
317 SetItalic( rFont
.GetItalic() );
318 if ( rFont
.mpImplFont
->GetWidthTypeNoAsk() != WIDTH_DONTKNOW
)
319 SetWidthType( rFont
.GetWidthType() );
321 if ( rFont
.GetFontSize().Height() )
322 SetFontSize( rFont
.GetFontSize() );
323 if ( rFont
.GetUnderline() != LINESTYLE_DONTKNOW
)
325 SetUnderline( rFont
.GetUnderline() );
326 SetWordLineMode( rFont
.IsWordLineMode() );
328 if ( rFont
.GetOverline() != LINESTYLE_DONTKNOW
)
330 SetOverline( rFont
.GetOverline() );
331 SetWordLineMode( rFont
.IsWordLineMode() );
333 if ( rFont
.GetStrikeout() != STRIKEOUT_DONTKNOW
)
335 SetStrikeout( rFont
.GetStrikeout() );
336 SetWordLineMode( rFont
.IsWordLineMode() );
340 SetOrientation( rFont
.GetOrientation() );
341 SetVertical( rFont
.IsVertical() );
342 SetEmphasisMark( rFont
.GetEmphasisMark() );
343 SetKerning( rFont
.IsKerning() ? FontKerning::FontSpecific
: FontKerning::NONE
);
344 SetOutline( rFont
.IsOutline() );
345 SetShadow( rFont
.IsShadow() );
346 SetRelief( rFont
.GetRelief() );
349 void Font::GetFontAttributes( FontAttributes
& rAttrs
) const
351 rAttrs
.SetFamilyName( mpImplFont
->GetFamilyName() );
352 rAttrs
.SetStyleName( mpImplFont
->maStyleName
);
353 rAttrs
.SetFamilyType( mpImplFont
->GetFamilyTypeNoAsk() );
354 rAttrs
.SetPitch( mpImplFont
->GetPitchNoAsk() );
355 rAttrs
.SetItalic( mpImplFont
->GetItalicNoAsk() );
356 rAttrs
.SetWeight( mpImplFont
->GetWeightNoAsk() );
357 rAttrs
.SetWidthType( WIDTH_DONTKNOW
);
358 rAttrs
.SetSymbolFlag( mpImplFont
->GetCharSet() == RTL_TEXTENCODING_SYMBOL
);
361 SvStream
& ReadImplFont( SvStream
& rIStm
, ImplFont
& rImplFont
)
363 VersionCompat
aCompat( rIStm
, StreamMode::READ
);
368 rImplFont
.SetFamilyName( rIStm
.ReadUniOrByteString(rIStm
.GetStreamCharSet()) );
369 rImplFont
.maStyleName
= rIStm
.ReadUniOrByteString(rIStm
.GetStreamCharSet());
370 ReadPair( rIStm
, rImplFont
.maAverageFontSize
);
372 rIStm
.ReadUInt16( nTmp16
); rImplFont
.SetCharSet( (rtl_TextEncoding
) nTmp16
);
373 rIStm
.ReadUInt16( nTmp16
); rImplFont
.SetFamilyType( (FontFamily
) nTmp16
);
374 rIStm
.ReadUInt16( nTmp16
); rImplFont
.SetPitch( (FontPitch
) nTmp16
);
375 rIStm
.ReadUInt16( nTmp16
); rImplFont
.SetWeight( (FontWeight
) nTmp16
);
376 rIStm
.ReadUInt16( nTmp16
); rImplFont
.meUnderline
= (FontLineStyle
) nTmp16
;
377 rIStm
.ReadUInt16( nTmp16
); rImplFont
.meStrikeout
= (FontStrikeout
) nTmp16
;
378 rIStm
.ReadUInt16( nTmp16
); rImplFont
.SetItalic( (FontItalic
) nTmp16
);
379 rIStm
.ReadUInt16( nTmp16
); rImplFont
.maLanguageTag
.reset( LanguageType(nTmp16
) );
380 rIStm
.ReadUInt16( nTmp16
); rImplFont
.meWidthType
= (FontWidth
) nTmp16
;
382 rIStm
.ReadInt16( rImplFont
.mnOrientation
);
384 rIStm
.ReadCharAsBool( bTmp
); rImplFont
.mbWordLine
= bTmp
;
385 rIStm
.ReadCharAsBool( bTmp
); rImplFont
.mbOutline
= bTmp
;
386 rIStm
.ReadCharAsBool( bTmp
); rImplFont
.mbShadow
= bTmp
;
387 rIStm
.ReadUChar( nTmp8
); rImplFont
.meKerning
= static_cast<FontKerning
>(nTmp8
);
389 if( aCompat
.GetVersion() >= 2 )
391 rIStm
.ReadUChar( nTmp8
); rImplFont
.meRelief
= (FontRelief
)nTmp8
;
392 rIStm
.ReadUInt16( nTmp16
); rImplFont
.maCJKLanguageTag
.reset( LanguageType(nTmp16
) );
393 rIStm
.ReadCharAsBool( bTmp
); rImplFont
.mbVertical
= bTmp
;
394 rIStm
.ReadUInt16( nTmp16
); rImplFont
.meEmphasisMark
= (FontEmphasisMark
)nTmp16
;
397 if( aCompat
.GetVersion() >= 3 )
399 rIStm
.ReadUInt16( nTmp16
); rImplFont
.meOverline
= (FontLineStyle
) nTmp16
;
403 // CJKContextLanguage
408 SvStream
& WriteImplFont( SvStream
& rOStm
, const ImplFont
& rImplFont
)
410 VersionCompat
aCompat( rOStm
, StreamMode::WRITE
, 3 );
411 rOStm
.WriteUniOrByteString( rImplFont
.GetFamilyName(), rOStm
.GetStreamCharSet() );
412 rOStm
.WriteUniOrByteString( rImplFont
.GetStyleName(), rOStm
.GetStreamCharSet() );
413 WritePair( rOStm
, rImplFont
.maAverageFontSize
);
415 rOStm
.WriteUInt16( GetStoreCharSet( rImplFont
.GetCharSet() ) );
416 rOStm
.WriteUInt16( rImplFont
.GetFamilyTypeNoAsk() );
417 rOStm
.WriteUInt16( rImplFont
.GetPitchNoAsk() );
418 rOStm
.WriteUInt16( rImplFont
.GetWeightNoAsk() );
419 rOStm
.WriteUInt16( rImplFont
.meUnderline
);
420 rOStm
.WriteUInt16( rImplFont
.meStrikeout
);
421 rOStm
.WriteUInt16( rImplFont
.GetItalicNoAsk() );
422 rOStm
.WriteUInt16( (sal_uInt16
)rImplFont
.maLanguageTag
.getLanguageType( false) );
423 rOStm
.WriteUInt16( rImplFont
.GetWidthTypeNoAsk() );
425 rOStm
.WriteInt16( rImplFont
.mnOrientation
);
427 rOStm
.WriteBool( rImplFont
.mbWordLine
);
428 rOStm
.WriteBool( rImplFont
.mbOutline
);
429 rOStm
.WriteBool( rImplFont
.mbShadow
);
430 rOStm
.WriteUChar( static_cast<sal_uInt8
>(rImplFont
.meKerning
) );
433 rOStm
.WriteUChar( (sal_uChar
)rImplFont
.meRelief
);
434 rOStm
.WriteUInt16( (sal_uInt16
)rImplFont
.maCJKLanguageTag
.getLanguageType( false) );
435 rOStm
.WriteBool( rImplFont
.mbVertical
);
436 rOStm
.WriteUInt16( (sal_uInt16
)rImplFont
.meEmphasisMark
);
439 rOStm
.WriteUInt16( rImplFont
.meOverline
);
444 SvStream
& ReadFont( SvStream
& rIStm
, vcl::Font
& rFont
)
446 return ReadImplFont( rIStm
, *rFont
.mpImplFont
);
449 SvStream
& WriteFont( SvStream
& rOStm
, const vcl::Font
& rFont
)
451 return WriteImplFont( rOStm
, *rFont
.mpImplFont
);
456 bool identifyTrueTypeFont( const void* i_pBuffer
, sal_uInt32 i_nSize
, Font
& o_rResult
)
458 bool bResult
= false;
459 TrueTypeFont
* pTTF
= nullptr;
460 if( OpenTTFontBuffer( i_pBuffer
, i_nSize
, 0, &pTTF
) == SF_OK
)
462 TTGlobalFontInfo aInfo
;
463 GetTTGlobalFontInfo( pTTF
, &aInfo
);
464 // most importantly: the family name
466 o_rResult
.SetFamilyName( aInfo
.ufamily
);
467 else if( aInfo
.family
)
468 o_rResult
.SetFamilyName( OStringToOUString( aInfo
.family
, RTL_TEXTENCODING_ASCII_US
) );
472 if( aInfo
.weight
< FW_EXTRALIGHT
)
473 o_rResult
.SetWeight( WEIGHT_THIN
);
474 else if( aInfo
.weight
< FW_LIGHT
)
475 o_rResult
.SetWeight( WEIGHT_ULTRALIGHT
);
476 else if( aInfo
.weight
< FW_NORMAL
)
477 o_rResult
.SetWeight( WEIGHT_LIGHT
);
478 else if( aInfo
.weight
< FW_MEDIUM
)
479 o_rResult
.SetWeight( WEIGHT_NORMAL
);
480 else if( aInfo
.weight
< FW_SEMIBOLD
)
481 o_rResult
.SetWeight( WEIGHT_MEDIUM
);
482 else if( aInfo
.weight
< FW_BOLD
)
483 o_rResult
.SetWeight( WEIGHT_SEMIBOLD
);
484 else if( aInfo
.weight
< FW_EXTRABOLD
)
485 o_rResult
.SetWeight( WEIGHT_BOLD
);
486 else if( aInfo
.weight
< FW_BLACK
)
487 o_rResult
.SetWeight( WEIGHT_ULTRABOLD
);
489 o_rResult
.SetWeight( WEIGHT_BLACK
);
492 o_rResult
.SetWeight( (aInfo
.macStyle
& 1) ? WEIGHT_BOLD
: WEIGHT_NORMAL
);
496 if( aInfo
.width
== FWIDTH_ULTRA_CONDENSED
)
497 o_rResult
.SetAverageFontWidth( WIDTH_ULTRA_CONDENSED
);
498 else if( aInfo
.width
== FWIDTH_EXTRA_CONDENSED
)
499 o_rResult
.SetAverageFontWidth( WIDTH_EXTRA_CONDENSED
);
500 else if( aInfo
.width
== FWIDTH_CONDENSED
)
501 o_rResult
.SetAverageFontWidth( WIDTH_CONDENSED
);
502 else if( aInfo
.width
== FWIDTH_SEMI_CONDENSED
)
503 o_rResult
.SetAverageFontWidth( WIDTH_SEMI_CONDENSED
);
504 else if( aInfo
.width
== FWIDTH_NORMAL
)
505 o_rResult
.SetAverageFontWidth( WIDTH_NORMAL
);
506 else if( aInfo
.width
== FWIDTH_SEMI_EXPANDED
)
507 o_rResult
.SetAverageFontWidth( WIDTH_SEMI_EXPANDED
);
508 else if( aInfo
.width
== FWIDTH_EXPANDED
)
509 o_rResult
.SetAverageFontWidth( WIDTH_EXPANDED
);
510 else if( aInfo
.width
== FWIDTH_EXTRA_EXPANDED
)
511 o_rResult
.SetAverageFontWidth( WIDTH_EXTRA_EXPANDED
);
512 else if( aInfo
.width
>= FWIDTH_ULTRA_EXPANDED
)
513 o_rResult
.SetAverageFontWidth( WIDTH_ULTRA_EXPANDED
);
516 o_rResult
.SetItalic( (aInfo
.italicAngle
!= 0) ? ITALIC_NORMAL
: ITALIC_NONE
);
519 o_rResult
.SetPitch( (aInfo
.pitch
== 0) ? PITCH_VARIABLE
: PITCH_FIXED
);
522 if( aInfo
.usubfamily
)
523 o_rResult
.SetStyleName( OUString( aInfo
.usubfamily
) );
524 else if( aInfo
.subfamily
)
525 o_rResult
.SetStyleName( OUString::createFromAscii( aInfo
.subfamily
) );
535 struct WeightSearchEntry
541 bool operator<( const WeightSearchEntry
& rRight
) const
543 return rtl_str_compareIgnoreAsciiCase_WithLength( string
, string_len
, rRight
.string
, rRight
.string_len
) < 0;
548 { "black", 5, WEIGHT_BLACK
},
549 { "bold", 4, WEIGHT_BOLD
},
550 { "book", 4, WEIGHT_LIGHT
},
551 { "demi", 4, WEIGHT_SEMIBOLD
},
552 { "heavy", 5, WEIGHT_BLACK
},
553 { "light", 5, WEIGHT_LIGHT
},
554 { "medium", 6, WEIGHT_MEDIUM
},
555 { "regular", 7, WEIGHT_NORMAL
},
556 { "super", 5, WEIGHT_ULTRABOLD
},
557 { "thin", 4, WEIGHT_THIN
}
560 bool identifyType1Font( const char* i_pBuffer
, sal_uInt32 i_nSize
, Font
& o_rResult
)
562 bool bResult
= false;
563 // might be a type1, find eexec
564 const char* pStream
= i_pBuffer
;
565 const char* const pExec
= "eexec";
566 const char* pExecPos
= std::search( pStream
, pStream
+i_nSize
, pExec
, pExec
+5 );
567 if( pExecPos
!= pStream
+i_nSize
)
569 // find /FamilyName entry
570 static const char* const pFam
= "/FamilyName";
571 const char* pFamPos
= std::search( pStream
, pExecPos
, pFam
, pFam
+11 );
572 if( pFamPos
!= pExecPos
)
574 // extract the string value behind /FamilyName
575 const char* pOpen
= pFamPos
+11;
576 while( pOpen
< pExecPos
&& *pOpen
!= '(' )
578 const char* pClose
= pOpen
;
579 while( pClose
< pExecPos
&& *pClose
!= ')' )
581 if( pClose
- pOpen
> 1 )
583 o_rResult
.SetFamilyName( OStringToOUString( OString( pOpen
+1, pClose
-pOpen
-1 ), RTL_TEXTENCODING_ASCII_US
) );
587 // parse /ItalicAngle
588 static const char* const pItalic
= "/ItalicAngle";
589 const char* pItalicPos
= std::search( pStream
, pExecPos
, pItalic
, pItalic
+12 );
590 if( pItalicPos
!= pExecPos
)
592 sal_Int32 nItalic
= rtl_str_toInt32( pItalicPos
+12, 10 );
593 o_rResult
.SetItalic( (nItalic
!= 0) ? ITALIC_NORMAL
: ITALIC_NONE
);
597 static const char* const pWeight
= "/Weight";
598 const char* pWeightPos
= std::search( pStream
, pExecPos
, pWeight
, pWeight
+7 );
599 if( pWeightPos
!= pExecPos
)
601 // extract the string value behind /Weight
602 const char* pOpen
= pWeightPos
+7;
603 while( pOpen
< pExecPos
&& *pOpen
!= '(' )
605 const char* pClose
= pOpen
;
606 while( pClose
< pExecPos
&& *pClose
!= ')' )
608 if( pClose
- pOpen
> 1 )
610 WeightSearchEntry aEnt
;
611 aEnt
.string
= pOpen
+1;
612 aEnt
.string_len
= (pClose
-pOpen
)-1;
613 aEnt
.weight
= WEIGHT_NORMAL
;
614 const int nEnt
= SAL_N_ELEMENTS( weight_table
);
615 WeightSearchEntry
* pFound
= std::lower_bound( weight_table
, weight_table
+nEnt
, aEnt
);
616 if( pFound
!= (weight_table
+nEnt
) )
617 o_rResult
.SetWeight( pFound
->weight
);
621 // parse isFixedPitch
622 static const char* const pFixed
= "/isFixedPitch";
623 const char* pFixedPos
= std::search( pStream
, pExecPos
, pFixed
, pFixed
+13 );
624 if( pFixedPos
!= pExecPos
)
627 while( pFixedPos
< pExecPos
-4 &&
628 ( *pFixedPos
== ' ' ||
629 *pFixedPos
== '\t' ||
630 *pFixedPos
== '\r' ||
631 *pFixedPos
== '\n' ) )
636 if( rtl_str_compareIgnoreAsciiCase_WithLength( pFixedPos
, 4, "true", 4 ) == 0 )
637 o_rResult
.SetPitch( PITCH_FIXED
);
639 o_rResult
.SetPitch( PITCH_VARIABLE
);
646 Font
Font::identifyFont( const void* i_pBuffer
, sal_uInt32 i_nSize
)
649 if( ! identifyTrueTypeFont( i_pBuffer
, i_nSize
, aResult
) )
651 const char* pStream
= static_cast<const char*>(i_pBuffer
);
652 if( pStream
&& i_nSize
> 100 &&
653 *pStream
== '%' && pStream
[1] == '!' )
655 identifyType1Font( pStream
, i_nSize
, aResult
);
662 // The inlines from the font.hxx header are now instantiated for pImpl-ification
663 const Color
& Font::GetColor() const { return mpImplFont
->maColor
; }
664 const Color
& Font::GetFillColor() const { return mpImplFont
->maFillColor
; }
665 bool Font::IsTransparent() const { return mpImplFont
->mbTransparent
; }
667 FontAlign
Font::GetAlignment() const { return mpImplFont
->GetAlignment(); }
669 const OUString
& Font::GetFamilyName() const { return mpImplFont
->GetFamilyName(); }
670 const OUString
& Font::GetStyleName() const { return mpImplFont
->maStyleName
; }
672 const Size
& Font::GetFontSize() const { return mpImplFont
->GetFontSize(); }
673 void Font::SetFontHeight( long nHeight
) { SetFontSize( Size( mpImplFont
->GetFontSize().Width(), nHeight
) ); }
674 long Font::GetFontHeight() const { return mpImplFont
->GetFontSize().Height(); }
675 void Font::SetAverageFontWidth( long nWidth
) { SetFontSize( Size( nWidth
, mpImplFont
->GetFontSize().Height() ) ); }
676 long Font::GetAverageFontWidth() const { return mpImplFont
->GetFontSize().Width(); }
678 rtl_TextEncoding
Font::GetCharSet() const { return mpImplFont
->GetCharSet(); }
680 const LanguageTag
& Font::GetLanguageTag() const { return mpImplFont
->maLanguageTag
; }
681 const LanguageTag
& Font::GetCJKContextLanguageTag() const { return mpImplFont
->maCJKLanguageTag
; }
682 LanguageType
Font::GetLanguage() const { return mpImplFont
->maLanguageTag
.getLanguageType( false); }
683 LanguageType
Font::GetCJKContextLanguage() const { return mpImplFont
->maCJKLanguageTag
.getLanguageType( false); }
685 short Font::GetOrientation() const { return mpImplFont
->mnOrientation
; }
686 bool Font::IsVertical() const { return mpImplFont
->mbVertical
; }
687 FontKerning
Font::GetKerning() const { return mpImplFont
->meKerning
; }
689 FontPitch
Font::GetPitch() { return mpImplFont
->GetPitch(); }
690 FontWeight
Font::GetWeight() { return mpImplFont
->GetWeight(); }
691 FontWidth
Font::GetWidthType() { return mpImplFont
->GetWidthType(); }
692 FontItalic
Font::GetItalic() { return mpImplFont
->GetItalic(); }
693 FontFamily
Font::GetFamilyType() { return mpImplFont
->GetFamilyType(); }
695 FontPitch
Font::GetPitch() const { return mpImplFont
->GetPitchNoAsk(); }
696 FontWeight
Font::GetWeight() const { return mpImplFont
->GetWeightNoAsk(); }
697 FontWidth
Font::GetWidthType() const { return mpImplFont
->GetWidthTypeNoAsk(); }
698 FontItalic
Font::GetItalic() const { return mpImplFont
->GetItalicNoAsk(); }
699 FontFamily
Font::GetFamilyType() const { return mpImplFont
->GetFamilyTypeNoAsk(); }
701 int Font::GetQuality() const { return mpImplFont
->GetQuality(); }
702 void Font::SetQuality( int nQuality
) { mpImplFont
->SetQuality( nQuality
); }
703 void Font::IncreaseQualityBy( int nQualityAmount
) { mpImplFont
->IncreaseQualityBy( nQualityAmount
); }
704 void Font::DecreaseQualityBy( int nQualityAmount
) { mpImplFont
->DecreaseQualityBy( nQualityAmount
); }
706 void Font::SetMapNames( OUString
const & aMapNames
) { mpImplFont
->SetMapNames(aMapNames
); }
708 bool Font::IsOutline() const { return mpImplFont
->mbOutline
; }
709 bool Font::IsShadow() const { return mpImplFont
->mbShadow
; }
710 FontRelief
Font::GetRelief() const { return mpImplFont
->meRelief
; }
711 FontLineStyle
Font::GetUnderline() const { return mpImplFont
->meUnderline
; }
712 FontLineStyle
Font::GetOverline() const { return mpImplFont
->meOverline
; }
713 FontStrikeout
Font::GetStrikeout() const { return mpImplFont
->meStrikeout
; }
714 FontEmphasisMark
Font::GetEmphasisMark() const { return mpImplFont
->meEmphasisMark
; }
715 bool Font::IsWordLineMode() const { return mpImplFont
->mbWordLine
; }
716 bool Font::IsSameInstance( const vcl::Font
& rFont
) const { return (mpImplFont
== rFont
.mpImplFont
); }
719 ImplFont::ImplFont() :
720 meWeight( WEIGHT_DONTKNOW
),
721 meFamily( FAMILY_DONTKNOW
),
722 mePitch( PITCH_DONTKNOW
),
723 meWidthType( WIDTH_DONTKNOW
),
724 meItalic( ITALIC_NONE
),
725 meAlign( ALIGN_TOP
),
726 meUnderline( LINESTYLE_NONE
),
727 meOverline( LINESTYLE_NONE
),
728 meStrikeout( STRIKEOUT_NONE
),
729 meRelief( FontRelief::NONE
),
730 meEmphasisMark( FontEmphasisMark::NONE
),
731 meKerning( FontKerning::FontSpecific
),
732 meCharSet( RTL_TEXTENCODING_DONTKNOW
),
733 maLanguageTag( LANGUAGE_DONTKNOW
),
734 maCJKLanguageTag( LANGUAGE_DONTKNOW
),
735 mbSymbolFlag( false ),
737 mbConfigLookup( false ),
740 mbTransparent( true ),
741 maColor( COL_TRANSPARENT
),
742 maFillColor( COL_TRANSPARENT
),
748 ImplFont::ImplFont( const ImplFont
& rImplFont
) :
749 maFamilyName( rImplFont
.maFamilyName
),
750 maStyleName( rImplFont
.maStyleName
),
751 meWeight( rImplFont
.meWeight
),
752 meFamily( rImplFont
.meFamily
),
753 mePitch( rImplFont
.mePitch
),
754 meWidthType( rImplFont
.meWidthType
),
755 meItalic( rImplFont
.meItalic
),
756 meAlign( rImplFont
.meAlign
),
757 meUnderline( rImplFont
.meUnderline
),
758 meOverline( rImplFont
.meOverline
),
759 meStrikeout( rImplFont
.meStrikeout
),
760 meRelief( rImplFont
.meRelief
),
761 meEmphasisMark( rImplFont
.meEmphasisMark
),
762 meKerning( rImplFont
.meKerning
),
763 maAverageFontSize( rImplFont
.maAverageFontSize
),
764 meCharSet( rImplFont
.meCharSet
),
765 maLanguageTag( rImplFont
.maLanguageTag
),
766 maCJKLanguageTag( rImplFont
.maCJKLanguageTag
),
767 mbSymbolFlag( rImplFont
.mbSymbolFlag
),
768 mbOutline( rImplFont
.mbOutline
),
769 mbConfigLookup( rImplFont
.mbConfigLookup
),
770 mbShadow( rImplFont
.mbShadow
),
771 mbVertical( rImplFont
.mbVertical
),
772 mbTransparent( rImplFont
.mbTransparent
),
773 maColor( rImplFont
.maColor
),
774 maFillColor( rImplFont
.maFillColor
),
775 maMapNames( rImplFont
.maMapNames
),
776 mbWordLine( rImplFont
.mbWordLine
),
777 mnOrientation( rImplFont
.mnOrientation
),
778 mnQuality( rImplFont
.mnQuality
)
781 bool ImplFont::operator==( const ImplFont
& rOther
) const
783 // equality tests split up for easier debugging
784 if( (meWeight
!= rOther
.meWeight
)
785 || (meItalic
!= rOther
.meItalic
)
786 || (meFamily
!= rOther
.meFamily
)
787 || (mePitch
!= rOther
.mePitch
) )
790 if( (meCharSet
!= rOther
.meCharSet
)
791 || (maLanguageTag
!= rOther
.maLanguageTag
)
792 || (maCJKLanguageTag
!= rOther
.maCJKLanguageTag
)
793 || (meAlign
!= rOther
.meAlign
) )
796 if( (maAverageFontSize
!= rOther
.maAverageFontSize
)
797 || (mnOrientation
!= rOther
.mnOrientation
)
798 || (mbVertical
!= rOther
.mbVertical
) )
801 if( (maFamilyName
!= rOther
.maFamilyName
)
802 || (maStyleName
!= rOther
.maStyleName
) )
805 if( (maColor
!= rOther
.maColor
)
806 || (maFillColor
!= rOther
.maFillColor
) )
809 if( (meUnderline
!= rOther
.meUnderline
)
810 || (meOverline
!= rOther
.meOverline
)
811 || (meStrikeout
!= rOther
.meStrikeout
)
812 || (meRelief
!= rOther
.meRelief
)
813 || (meEmphasisMark
!= rOther
.meEmphasisMark
)
814 || (mbWordLine
!= rOther
.mbWordLine
)
815 || (mbOutline
!= rOther
.mbOutline
)
816 || (mbShadow
!= rOther
.mbShadow
)
817 || (meKerning
!= rOther
.meKerning
)
818 || (mbTransparent
!= rOther
.mbTransparent
) )
824 void ImplFont::AskConfig()
829 mbConfigLookup
= true;
831 // prepare the FontSubst configuration lookup
832 const utl::FontSubstConfiguration
& rFontSubst
= utl::FontSubstConfiguration::get();
835 OUString aFamilyName
;
836 ImplFontAttrs nType
= ImplFontAttrs::None
;
837 FontWeight eWeight
= WEIGHT_DONTKNOW
;
838 FontWidth eWidthType
= WIDTH_DONTKNOW
;
839 OUString aMapName
= GetEnglishSearchFontName( maFamilyName
);
841 utl::FontSubstConfiguration::getMapName( aMapName
,
842 aShortName
, aFamilyName
, eWeight
, eWidthType
, nType
);
844 // lookup the font name in the configuration
845 const utl::FontNameAttr
* pFontAttr
= rFontSubst
.getSubstInfo( aMapName
);
847 // if the direct lookup failed try again with an alias name
848 if ( !pFontAttr
&& (aShortName
!= aMapName
) )
849 pFontAttr
= rFontSubst
.getSubstInfo( aShortName
);
853 // the font was found in the configuration
854 if( meFamily
== FAMILY_DONTKNOW
)
856 if ( pFontAttr
->Type
& ImplFontAttrs::Serif
)
857 meFamily
= FAMILY_ROMAN
;
858 else if ( pFontAttr
->Type
& ImplFontAttrs::SansSerif
)
859 meFamily
= FAMILY_SWISS
;
860 else if ( pFontAttr
->Type
& ImplFontAttrs::Typewriter
)
861 meFamily
= FAMILY_MODERN
;
862 else if ( pFontAttr
->Type
& ImplFontAttrs::Italic
)
863 meFamily
= FAMILY_SCRIPT
;
864 else if ( pFontAttr
->Type
& ImplFontAttrs::Decorative
)
865 meFamily
= FAMILY_DECORATIVE
;
868 if( mePitch
== PITCH_DONTKNOW
)
870 if ( pFontAttr
->Type
& ImplFontAttrs::Fixed
)
871 mePitch
= PITCH_FIXED
;
875 // if some attributes are still unknown then use the FontSubst magic
876 if( meFamily
== FAMILY_DONTKNOW
)
878 if( nType
& ImplFontAttrs::Serif
)
879 meFamily
= FAMILY_ROMAN
;
880 else if( nType
& ImplFontAttrs::SansSerif
)
881 meFamily
= FAMILY_SWISS
;
882 else if( nType
& ImplFontAttrs::Typewriter
)
883 meFamily
= FAMILY_MODERN
;
884 else if( nType
& ImplFontAttrs::Italic
)
885 meFamily
= FAMILY_SCRIPT
;
886 else if( nType
& ImplFontAttrs::Decorative
)
887 meFamily
= FAMILY_DECORATIVE
;
890 if( GetWeight() == WEIGHT_DONTKNOW
)
891 SetWeight( eWeight
);
892 if( meWidthType
== WIDTH_DONTKNOW
)
893 meWidthType
= eWidthType
;
896 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */