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/debug.hxx>
24 #include <tools/gen.hxx>
25 #include <unotools/fontcfg.hxx>
26 #include <unotools/fontdefs.hxx>
28 #include <vcl/font.hxx>
30 #include "impfont.hxx"
31 #include "fontinstance.hxx"
32 #include "fontattributes.hxx"
37 #include <rtl/instance.hxx>
43 struct theGlobalDefault
:
44 public rtl::Static
< Font::ImplType
, theGlobalDefault
> {};
47 Font::Font() : mpImplFont(theGlobalDefault::get())
51 Font::Font( const vcl::Font
& rFont
) : mpImplFont( rFont
.mpImplFont
)
55 Font::Font( vcl::Font
&& rFont
) : mpImplFont( std::move(rFont
.mpImplFont
) )
59 Font::Font( const OUString
& rFamilyName
, const Size
& rSize
) : mpImplFont()
61 mpImplFont
->SetFamilyName( rFamilyName
);
62 mpImplFont
->SetFontSize( rSize
);
65 Font::Font( const OUString
& rFamilyName
, const OUString
& rStyleName
, const Size
& rSize
) : mpImplFont()
67 mpImplFont
->SetFamilyName( rFamilyName
);
68 mpImplFont
->SetStyleName( rStyleName
);
69 mpImplFont
->SetFontSize( rSize
);
72 Font::Font( FontFamily eFamily
, const Size
& rSize
) : mpImplFont()
74 mpImplFont
->SetFamilyType( eFamily
);
75 mpImplFont
->SetFontSize( rSize
);
82 void Font::SetColor( const Color
& rColor
)
84 if( mpImplFont
->maColor
!= rColor
)
86 mpImplFont
->maColor
= rColor
;
90 void Font::SetFillColor( const Color
& rColor
)
92 mpImplFont
->maFillColor
= rColor
;
93 if ( rColor
.GetTransparency() )
94 mpImplFont
->mbTransparent
= true;
97 void Font::SetTransparent( bool bTransparent
)
99 if( mpImplFont
->mbTransparent
!= bTransparent
)
100 mpImplFont
->mbTransparent
= bTransparent
;
103 void Font::SetAlignment( FontAlign eAlign
)
105 if( mpImplFont
->meAlign
!= eAlign
)
106 mpImplFont
->SetAlignment(eAlign
);
109 void Font::SetFamilyName( const OUString
& rFamilyName
)
111 mpImplFont
->SetFamilyName( rFamilyName
);
114 void Font::SetStyleName( const OUString
& rStyleName
)
116 mpImplFont
->maStyleName
= rStyleName
;
119 void Font::SetFontSize( const Size
& rSize
)
121 if( mpImplFont
->GetFontSize() != rSize
)
122 mpImplFont
->SetFontSize( rSize
);
125 void Font::SetFamily( FontFamily eFamily
)
127 if( mpImplFont
->GetFamilyTypeNoAsk() != eFamily
)
128 mpImplFont
->SetFamilyType( eFamily
);
131 void Font::SetCharSet( rtl_TextEncoding eCharSet
)
133 if( mpImplFont
->GetCharSet() != eCharSet
)
135 mpImplFont
->SetCharSet( eCharSet
);
137 if ( eCharSet
== RTL_TEXTENCODING_SYMBOL
)
138 mpImplFont
->SetSymbolFlag( true );
140 mpImplFont
->SetSymbolFlag( false );
144 bool Font::IsSymbolFont() const
146 return mpImplFont
->IsSymbolFont();
149 void Font::SetSymbolFlag( bool bSymbol
)
151 mpImplFont
->SetSymbolFlag( bSymbol
);
153 if ( IsSymbolFont() )
155 mpImplFont
->SetCharSet( RTL_TEXTENCODING_SYMBOL
);
159 if ( mpImplFont
->GetCharSet() == RTL_TEXTENCODING_SYMBOL
)
160 mpImplFont
->SetCharSet( RTL_TEXTENCODING_DONTKNOW
);
164 void Font::SetLanguageTag( const LanguageTag
& rLanguageTag
)
166 if( mpImplFont
->maLanguageTag
!= rLanguageTag
)
167 mpImplFont
->maLanguageTag
= rLanguageTag
;
170 void Font::SetCJKContextLanguageTag( const LanguageTag
& rLanguageTag
)
172 if( mpImplFont
->maCJKLanguageTag
!= rLanguageTag
)
173 mpImplFont
->maCJKLanguageTag
= rLanguageTag
;
176 void Font::SetLanguage( LanguageType eLanguage
)
178 if( mpImplFont
->maLanguageTag
.getLanguageType( false) != eLanguage
)
179 mpImplFont
->maLanguageTag
.reset( eLanguage
);
182 void Font::SetCJKContextLanguage( LanguageType eLanguage
)
184 if( mpImplFont
->maCJKLanguageTag
.getLanguageType( false) != eLanguage
)
185 mpImplFont
->maCJKLanguageTag
.reset( eLanguage
);
188 void Font::SetPitch( FontPitch ePitch
)
190 if( mpImplFont
->GetPitchNoAsk() != ePitch
)
191 mpImplFont
->SetPitch( ePitch
);
194 void Font::SetOrientation( short nOrientation
)
196 if( mpImplFont
->mnOrientation
!= nOrientation
)
197 mpImplFont
->mnOrientation
= nOrientation
;
200 void Font::SetVertical( bool bVertical
)
202 if( mpImplFont
->mbVertical
!= bVertical
)
203 mpImplFont
->mbVertical
= bVertical
;
206 void Font::SetKerning( FontKerning eKerning
)
208 if( mpImplFont
->meKerning
!= eKerning
)
209 mpImplFont
->meKerning
= eKerning
;
212 bool Font::IsKerning() const
214 return bool(mpImplFont
->meKerning
& FontKerning::FontSpecific
);
217 void Font::SetWeight( FontWeight eWeight
)
219 if( mpImplFont
->GetWeightNoAsk() != eWeight
)
220 mpImplFont
->SetWeight( eWeight
);
223 void Font::SetWidthType( FontWidth eWidth
)
225 if( mpImplFont
->GetWidthTypeNoAsk() != eWidth
)
226 mpImplFont
->SetWidthType( eWidth
);
229 void Font::SetItalic( FontItalic eItalic
)
231 if( mpImplFont
->GetItalicNoAsk() != eItalic
)
232 mpImplFont
->SetItalic( eItalic
);
235 void Font::SetOutline( bool bOutline
)
237 if( mpImplFont
->mbOutline
!= bOutline
)
238 mpImplFont
->mbOutline
= bOutline
;
241 void Font::SetShadow( bool bShadow
)
243 if( mpImplFont
->mbShadow
!= bShadow
)
244 mpImplFont
->mbShadow
= bShadow
;
247 void Font::SetUnderline( FontLineStyle eUnderline
)
249 if( mpImplFont
->meUnderline
!= eUnderline
)
250 mpImplFont
->meUnderline
= eUnderline
;
253 void Font::SetOverline( FontLineStyle eOverline
)
255 if( mpImplFont
->meOverline
!= eOverline
)
256 mpImplFont
->meOverline
= eOverline
;
259 void Font::SetStrikeout( FontStrikeout eStrikeout
)
261 if( mpImplFont
->meStrikeout
!= eStrikeout
)
262 mpImplFont
->meStrikeout
= eStrikeout
;
265 void Font::SetRelief( FontRelief eRelief
)
267 if( mpImplFont
->meRelief
!= eRelief
)
268 mpImplFont
->meRelief
= eRelief
;
271 void Font::SetEmphasisMark( FontEmphasisMark eEmphasisMark
)
273 if( mpImplFont
->meEmphasisMark
!= eEmphasisMark
)
274 mpImplFont
->meEmphasisMark
= eEmphasisMark
;
277 void Font::SetWordLineMode( bool bWordLine
)
279 if( mpImplFont
->mbWordLine
!= bWordLine
)
280 mpImplFont
->mbWordLine
= bWordLine
;
283 Font
& Font::operator=( const vcl::Font
& rFont
)
285 mpImplFont
= rFont
.mpImplFont
;
289 Font
& Font::operator=( vcl::Font
&& rFont
)
291 mpImplFont
= std::move(rFont
.mpImplFont
);
295 bool Font::operator==( const vcl::Font
& rFont
) const
297 return mpImplFont
== rFont
.mpImplFont
;
300 void Font::Merge( const vcl::Font
& rFont
)
302 if ( !rFont
.GetFamilyName().isEmpty() )
304 SetFamilyName( rFont
.GetFamilyName() );
305 SetStyleName( rFont
.GetStyleName() );
306 SetCharSet( GetCharSet() );
307 SetLanguageTag( rFont
.GetLanguageTag() );
308 SetCJKContextLanguageTag( rFont
.GetCJKContextLanguageTag() );
309 // don't use access methods here, might lead to AskConfig(), if DONTKNOW
310 SetFamily( rFont
.mpImplFont
->GetFamilyTypeNoAsk() );
311 SetPitch( rFont
.mpImplFont
->GetPitchNoAsk() );
314 // don't use access methods here, might lead to AskConfig(), if DONTKNOW
315 if ( rFont
.mpImplFont
->GetWeightNoAsk() != WEIGHT_DONTKNOW
)
316 SetWeight( rFont
.GetWeight() );
317 if ( rFont
.mpImplFont
->GetItalicNoAsk() != ITALIC_DONTKNOW
)
318 SetItalic( rFont
.GetItalic() );
319 if ( rFont
.mpImplFont
->GetWidthTypeNoAsk() != WIDTH_DONTKNOW
)
320 SetWidthType( rFont
.GetWidthType() );
322 if ( rFont
.GetFontSize().Height() )
323 SetFontSize( rFont
.GetFontSize() );
324 if ( rFont
.GetUnderline() != LINESTYLE_DONTKNOW
)
326 SetUnderline( rFont
.GetUnderline() );
327 SetWordLineMode( rFont
.IsWordLineMode() );
329 if ( rFont
.GetOverline() != LINESTYLE_DONTKNOW
)
331 SetOverline( rFont
.GetOverline() );
332 SetWordLineMode( rFont
.IsWordLineMode() );
334 if ( rFont
.GetStrikeout() != STRIKEOUT_DONTKNOW
)
336 SetStrikeout( rFont
.GetStrikeout() );
337 SetWordLineMode( rFont
.IsWordLineMode() );
341 SetOrientation( rFont
.GetOrientation() );
342 SetVertical( rFont
.IsVertical() );
343 SetEmphasisMark( rFont
.GetEmphasisMark() );
344 SetKerning( rFont
.IsKerning() ? FontKerning::FontSpecific
: FontKerning::NONE
);
345 SetOutline( rFont
.IsOutline() );
346 SetShadow( rFont
.IsShadow() );
347 SetRelief( rFont
.GetRelief() );
350 void Font::GetFontAttributes( FontAttributes
& rAttrs
) const
352 rAttrs
.SetFamilyName( mpImplFont
->GetFamilyName() );
353 rAttrs
.SetStyleName( mpImplFont
->maStyleName
);
354 rAttrs
.SetFamilyType( mpImplFont
->GetFamilyTypeNoAsk() );
355 rAttrs
.SetPitch( mpImplFont
->GetPitchNoAsk() );
356 rAttrs
.SetItalic( mpImplFont
->GetItalicNoAsk() );
357 rAttrs
.SetWeight( mpImplFont
->GetWeightNoAsk() );
358 rAttrs
.SetWidthType( WIDTH_DONTKNOW
);
359 rAttrs
.SetSymbolFlag( mpImplFont
->GetCharSet() == RTL_TEXTENCODING_SYMBOL
);
362 SvStream
& ReadImplFont( SvStream
& rIStm
, ImplFont
& rImplFont
)
364 VersionCompat
aCompat( rIStm
, StreamMode::READ
);
369 rImplFont
.SetFamilyName( rIStm
.ReadUniOrByteString(rIStm
.GetStreamCharSet()) );
370 rImplFont
.maStyleName
= rIStm
.ReadUniOrByteString(rIStm
.GetStreamCharSet());
371 ReadPair( rIStm
, rImplFont
.maAverageFontSize
);
373 rIStm
.ReadUInt16( nTmp16
); rImplFont
.SetCharSet( (rtl_TextEncoding
) nTmp16
);
374 rIStm
.ReadUInt16( nTmp16
); rImplFont
.SetFamilyType( (FontFamily
) nTmp16
);
375 rIStm
.ReadUInt16( nTmp16
); rImplFont
.SetPitch( (FontPitch
) nTmp16
);
376 rIStm
.ReadUInt16( nTmp16
); rImplFont
.SetWeight( (FontWeight
) nTmp16
);
377 rIStm
.ReadUInt16( nTmp16
); rImplFont
.meUnderline
= (FontLineStyle
) nTmp16
;
378 rIStm
.ReadUInt16( nTmp16
); rImplFont
.meStrikeout
= (FontStrikeout
) nTmp16
;
379 rIStm
.ReadUInt16( nTmp16
); rImplFont
.SetItalic( (FontItalic
) nTmp16
);
380 rIStm
.ReadUInt16( nTmp16
); rImplFont
.maLanguageTag
.reset( (LanguageType
) nTmp16
);
381 rIStm
.ReadUInt16( nTmp16
); rImplFont
.meWidthType
= (FontWidth
) nTmp16
;
383 rIStm
.ReadInt16( rImplFont
.mnOrientation
);
385 rIStm
.ReadCharAsBool( bTmp
); rImplFont
.mbWordLine
= bTmp
;
386 rIStm
.ReadCharAsBool( bTmp
); rImplFont
.mbOutline
= bTmp
;
387 rIStm
.ReadCharAsBool( bTmp
); rImplFont
.mbShadow
= bTmp
;
388 rIStm
.ReadUChar( nTmp8
); rImplFont
.meKerning
= static_cast<FontKerning
>(nTmp8
);
390 if( aCompat
.GetVersion() >= 2 )
392 rIStm
.ReadUChar( nTmp8
); rImplFont
.meRelief
= (FontRelief
)nTmp8
;
393 rIStm
.ReadUInt16( nTmp16
); rImplFont
.maCJKLanguageTag
.reset( (LanguageType
)nTmp16
);
394 rIStm
.ReadCharAsBool( bTmp
); rImplFont
.mbVertical
= bTmp
;
395 rIStm
.ReadUInt16( nTmp16
); rImplFont
.meEmphasisMark
= (FontEmphasisMark
)nTmp16
;
398 if( aCompat
.GetVersion() >= 3 )
400 rIStm
.ReadUInt16( nTmp16
); rImplFont
.meOverline
= (FontLineStyle
) nTmp16
;
404 // CJKContextLanguage
409 SvStream
& WriteImplFont( SvStream
& rOStm
, const ImplFont
& rImplFont
)
411 VersionCompat
aCompat( rOStm
, StreamMode::WRITE
, 3 );
412 rOStm
.WriteUniOrByteString( rImplFont
.GetFamilyName(), rOStm
.GetStreamCharSet() );
413 rOStm
.WriteUniOrByteString( rImplFont
.GetStyleName(), rOStm
.GetStreamCharSet() );
414 WritePair( rOStm
, rImplFont
.maAverageFontSize
);
416 rOStm
.WriteUInt16( GetStoreCharSet( rImplFont
.GetCharSet() ) );
417 rOStm
.WriteUInt16( rImplFont
.GetFamilyTypeNoAsk() );
418 rOStm
.WriteUInt16( rImplFont
.GetPitchNoAsk() );
419 rOStm
.WriteUInt16( rImplFont
.GetWeightNoAsk() );
420 rOStm
.WriteUInt16( rImplFont
.meUnderline
);
421 rOStm
.WriteUInt16( rImplFont
.meStrikeout
);
422 rOStm
.WriteUInt16( rImplFont
.GetItalicNoAsk() );
423 rOStm
.WriteUInt16( rImplFont
.maLanguageTag
.getLanguageType( false) );
424 rOStm
.WriteUInt16( rImplFont
.GetWidthTypeNoAsk() );
426 rOStm
.WriteInt16( rImplFont
.mnOrientation
);
428 rOStm
.WriteBool( rImplFont
.mbWordLine
);
429 rOStm
.WriteBool( rImplFont
.mbOutline
);
430 rOStm
.WriteBool( rImplFont
.mbShadow
);
431 rOStm
.WriteUChar( static_cast<sal_uInt8
>(rImplFont
.meKerning
) );
434 rOStm
.WriteUChar( (sal_uChar
)rImplFont
.meRelief
);
435 rOStm
.WriteUInt16( rImplFont
.maCJKLanguageTag
.getLanguageType( false) );
436 rOStm
.WriteBool( rImplFont
.mbVertical
);
437 rOStm
.WriteUInt16( (sal_uInt16
)rImplFont
.meEmphasisMark
);
440 rOStm
.WriteUInt16( rImplFont
.meOverline
);
445 SvStream
& ReadFont( SvStream
& rIStm
, vcl::Font
& rFont
)
447 return ReadImplFont( rIStm
, *rFont
.mpImplFont
);
450 SvStream
& WriteFont( SvStream
& rOStm
, const vcl::Font
& rFont
)
452 return WriteImplFont( rOStm
, *rFont
.mpImplFont
);
457 bool identifyTrueTypeFont( const void* i_pBuffer
, sal_uInt32 i_nSize
, Font
& o_rResult
)
459 bool bResult
= false;
460 TrueTypeFont
* pTTF
= nullptr;
461 if( OpenTTFontBuffer( i_pBuffer
, i_nSize
, 0, &pTTF
) == SF_OK
)
463 TTGlobalFontInfo aInfo
;
464 GetTTGlobalFontInfo( pTTF
, &aInfo
);
465 // most importantly: the family name
467 o_rResult
.SetFamilyName( aInfo
.ufamily
);
468 else if( aInfo
.family
)
469 o_rResult
.SetFamilyName( OStringToOUString( aInfo
.family
, RTL_TEXTENCODING_ASCII_US
) );
473 if( aInfo
.weight
< FW_EXTRALIGHT
)
474 o_rResult
.SetWeight( WEIGHT_THIN
);
475 else if( aInfo
.weight
< FW_LIGHT
)
476 o_rResult
.SetWeight( WEIGHT_ULTRALIGHT
);
477 else if( aInfo
.weight
< FW_NORMAL
)
478 o_rResult
.SetWeight( WEIGHT_LIGHT
);
479 else if( aInfo
.weight
< FW_MEDIUM
)
480 o_rResult
.SetWeight( WEIGHT_NORMAL
);
481 else if( aInfo
.weight
< FW_SEMIBOLD
)
482 o_rResult
.SetWeight( WEIGHT_MEDIUM
);
483 else if( aInfo
.weight
< FW_BOLD
)
484 o_rResult
.SetWeight( WEIGHT_SEMIBOLD
);
485 else if( aInfo
.weight
< FW_EXTRABOLD
)
486 o_rResult
.SetWeight( WEIGHT_BOLD
);
487 else if( aInfo
.weight
< FW_BLACK
)
488 o_rResult
.SetWeight( WEIGHT_ULTRABOLD
);
490 o_rResult
.SetWeight( WEIGHT_BLACK
);
493 o_rResult
.SetWeight( (aInfo
.macStyle
& 1) ? WEIGHT_BOLD
: WEIGHT_NORMAL
);
497 if( aInfo
.width
== FWIDTH_ULTRA_CONDENSED
)
498 o_rResult
.SetAverageFontWidth( WIDTH_ULTRA_CONDENSED
);
499 else if( aInfo
.width
== FWIDTH_EXTRA_CONDENSED
)
500 o_rResult
.SetAverageFontWidth( WIDTH_EXTRA_CONDENSED
);
501 else if( aInfo
.width
== FWIDTH_CONDENSED
)
502 o_rResult
.SetAverageFontWidth( WIDTH_CONDENSED
);
503 else if( aInfo
.width
== FWIDTH_SEMI_CONDENSED
)
504 o_rResult
.SetAverageFontWidth( WIDTH_SEMI_CONDENSED
);
505 else if( aInfo
.width
== FWIDTH_NORMAL
)
506 o_rResult
.SetAverageFontWidth( WIDTH_NORMAL
);
507 else if( aInfo
.width
== FWIDTH_SEMI_EXPANDED
)
508 o_rResult
.SetAverageFontWidth( WIDTH_SEMI_EXPANDED
);
509 else if( aInfo
.width
== FWIDTH_EXPANDED
)
510 o_rResult
.SetAverageFontWidth( WIDTH_EXPANDED
);
511 else if( aInfo
.width
== FWIDTH_EXTRA_EXPANDED
)
512 o_rResult
.SetAverageFontWidth( WIDTH_EXTRA_EXPANDED
);
513 else if( aInfo
.width
>= FWIDTH_ULTRA_EXPANDED
)
514 o_rResult
.SetAverageFontWidth( WIDTH_ULTRA_EXPANDED
);
517 o_rResult
.SetItalic( (aInfo
.italicAngle
!= 0) ? ITALIC_NORMAL
: ITALIC_NONE
);
520 o_rResult
.SetPitch( (aInfo
.pitch
== 0) ? PITCH_VARIABLE
: PITCH_FIXED
);
523 if( aInfo
.usubfamily
)
524 o_rResult
.SetStyleName( OUString( aInfo
.usubfamily
) );
525 else if( aInfo
.subfamily
)
526 o_rResult
.SetStyleName( OUString::createFromAscii( aInfo
.subfamily
) );
536 struct WeightSearchEntry
542 bool operator<( const WeightSearchEntry
& rRight
) const
544 return rtl_str_compareIgnoreAsciiCase_WithLength( string
, string_len
, rRight
.string
, rRight
.string_len
) < 0;
549 { "black", 5, WEIGHT_BLACK
},
550 { "bold", 4, WEIGHT_BOLD
},
551 { "book", 4, WEIGHT_LIGHT
},
552 { "demi", 4, WEIGHT_SEMIBOLD
},
553 { "heavy", 5, WEIGHT_BLACK
},
554 { "light", 5, WEIGHT_LIGHT
},
555 { "medium", 6, WEIGHT_MEDIUM
},
556 { "regular", 7, WEIGHT_NORMAL
},
557 { "super", 5, WEIGHT_ULTRABOLD
},
558 { "thin", 4, WEIGHT_THIN
}
561 bool identifyType1Font( const char* i_pBuffer
, sal_uInt32 i_nSize
, Font
& o_rResult
)
563 bool bResult
= false;
564 // might be a type1, find eexec
565 const char* pStream
= i_pBuffer
;
566 const char* pExec
= "eexec";
567 const char* pExecPos
= std::search( pStream
, pStream
+i_nSize
, pExec
, pExec
+5 );
568 if( pExecPos
!= pStream
+i_nSize
)
570 // find /FamilyName entry
571 static const char* pFam
= "/FamilyName";
572 const char* pFamPos
= std::search( pStream
, pExecPos
, pFam
, pFam
+11 );
573 if( pFamPos
!= pExecPos
)
575 // extract the string value behind /FamilyName
576 const char* pOpen
= pFamPos
+11;
577 while( pOpen
< pExecPos
&& *pOpen
!= '(' )
579 const char* pClose
= pOpen
;
580 while( pClose
< pExecPos
&& *pClose
!= ')' )
582 if( pClose
- pOpen
> 1 )
584 o_rResult
.SetFamilyName( OStringToOUString( OString( pOpen
+1, pClose
-pOpen
-1 ), RTL_TEXTENCODING_ASCII_US
) );
588 // parse /ItalicAngle
589 static const char* pItalic
= "/ItalicAngle";
590 const char* pItalicPos
= std::search( pStream
, pExecPos
, pItalic
, pItalic
+12 );
591 if( pItalicPos
!= pExecPos
)
593 sal_Int32 nItalic
= rtl_str_toInt32( pItalicPos
+12, 10 );
594 o_rResult
.SetItalic( (nItalic
!= 0) ? ITALIC_NORMAL
: ITALIC_NONE
);
598 static const char* pWeight
= "/Weight";
599 const char* pWeightPos
= std::search( pStream
, pExecPos
, pWeight
, pWeight
+7 );
600 if( pWeightPos
!= pExecPos
)
602 // extract the string value behind /Weight
603 const char* pOpen
= pWeightPos
+7;
604 while( pOpen
< pExecPos
&& *pOpen
!= '(' )
606 const char* pClose
= pOpen
;
607 while( pClose
< pExecPos
&& *pClose
!= ')' )
609 if( pClose
- pOpen
> 1 )
611 WeightSearchEntry aEnt
;
612 aEnt
.string
= pOpen
+1;
613 aEnt
.string_len
= (pClose
-pOpen
)-1;
614 aEnt
.weight
= WEIGHT_NORMAL
;
615 const int nEnt
= SAL_N_ELEMENTS( weight_table
);
616 WeightSearchEntry
* pFound
= std::lower_bound( weight_table
, weight_table
+nEnt
, aEnt
);
617 if( pFound
!= (weight_table
+nEnt
) )
618 o_rResult
.SetWeight( pFound
->weight
);
622 // parse isFixedPitch
623 static const char* pFixed
= "/isFixedPitch";
624 const char* pFixedPos
= std::search( pStream
, pExecPos
, pFixed
, pFixed
+13 );
625 if( pFixedPos
!= pExecPos
)
628 while( pFixedPos
< pExecPos
-4 &&
629 ( *pFixedPos
== ' ' ||
630 *pFixedPos
== '\t' ||
631 *pFixedPos
== '\r' ||
632 *pFixedPos
== '\n' ) )
637 if( rtl_str_compareIgnoreAsciiCase_WithLength( pFixedPos
, 4, "true", 4 ) == 0 )
638 o_rResult
.SetPitch( PITCH_FIXED
);
640 o_rResult
.SetPitch( PITCH_VARIABLE
);
647 Font
Font::identifyFont( const void* i_pBuffer
, sal_uInt32 i_nSize
)
650 if( ! identifyTrueTypeFont( i_pBuffer
, i_nSize
, aResult
) )
652 const char* pStream
= static_cast<const char*>(i_pBuffer
);
653 if( pStream
&& i_nSize
> 100 &&
654 *pStream
== '%' && pStream
[1] == '!' )
656 identifyType1Font( pStream
, i_nSize
, aResult
);
663 // The inlines from the font.hxx header are now instantiated for pImpl-ification
664 const Color
& Font::GetColor() const { return mpImplFont
->maColor
; }
665 const Color
& Font::GetFillColor() const { return mpImplFont
->maFillColor
; }
666 bool Font::IsTransparent() const { return mpImplFont
->mbTransparent
; }
668 FontAlign
Font::GetAlignment() const { return mpImplFont
->GetAlignment(); }
670 const OUString
& Font::GetFamilyName() const { return mpImplFont
->GetFamilyName(); }
671 const OUString
& Font::GetStyleName() const { return mpImplFont
->maStyleName
; }
673 const Size
& Font::GetFontSize() const { return mpImplFont
->GetFontSize(); }
674 void Font::SetFontHeight( long nHeight
) { SetFontSize( Size( mpImplFont
->GetFontSize().Width(), nHeight
) ); }
675 long Font::GetFontHeight() const { return mpImplFont
->GetFontSize().Height(); }
676 void Font::SetAverageFontWidth( long nWidth
) { SetFontSize( Size( nWidth
, mpImplFont
->GetFontSize().Height() ) ); }
677 long Font::GetAverageFontWidth() const { return mpImplFont
->GetFontSize().Width(); }
679 rtl_TextEncoding
Font::GetCharSet() const { return mpImplFont
->GetCharSet(); }
681 const LanguageTag
& Font::GetLanguageTag() const { return mpImplFont
->maLanguageTag
; }
682 const LanguageTag
& Font::GetCJKContextLanguageTag() const { return mpImplFont
->maCJKLanguageTag
; }
683 LanguageType
Font::GetLanguage() const { return mpImplFont
->maLanguageTag
.getLanguageType( false); }
684 LanguageType
Font::GetCJKContextLanguage() const { return mpImplFont
->maCJKLanguageTag
.getLanguageType( false); }
686 short Font::GetOrientation() const { return mpImplFont
->mnOrientation
; }
687 bool Font::IsVertical() const { return mpImplFont
->mbVertical
; }
688 FontKerning
Font::GetKerning() const { return mpImplFont
->meKerning
; }
690 FontPitch
Font::GetPitch() { return mpImplFont
->GetPitch(); }
691 FontWeight
Font::GetWeight() { return mpImplFont
->GetWeight(); }
692 FontWidth
Font::GetWidthType() { return mpImplFont
->GetWidthType(); }
693 FontItalic
Font::GetItalic() { return mpImplFont
->GetItalic(); }
694 FontFamily
Font::GetFamilyType() { return mpImplFont
->GetFamilyType(); }
696 FontPitch
Font::GetPitch() const { return mpImplFont
->GetPitchNoAsk(); }
697 FontWeight
Font::GetWeight() const { return mpImplFont
->GetWeightNoAsk(); }
698 FontWidth
Font::GetWidthType() const { return mpImplFont
->GetWidthTypeNoAsk(); }
699 FontItalic
Font::GetItalic() const { return mpImplFont
->GetItalicNoAsk(); }
700 FontFamily
Font::GetFamilyType() const { return mpImplFont
->GetFamilyTypeNoAsk(); }
702 int Font::GetQuality() const { return mpImplFont
->GetQuality(); }
703 void Font::SetQuality( int nQuality
) { mpImplFont
->SetQuality( nQuality
); }
704 void Font::IncreaseQualityBy( int nQualityAmount
) { mpImplFont
->IncreaseQualityBy( nQualityAmount
); }
705 void Font::DecreaseQualityBy( int nQualityAmount
) { mpImplFont
->DecreaseQualityBy( nQualityAmount
); }
707 void Font::SetMapNames( OUString
const & aMapNames
) { mpImplFont
->SetMapNames(aMapNames
); }
709 bool Font::IsOutline() const { return mpImplFont
->mbOutline
; }
710 bool Font::IsShadow() const { return mpImplFont
->mbShadow
; }
711 FontRelief
Font::GetRelief() const { return mpImplFont
->meRelief
; }
712 FontLineStyle
Font::GetUnderline() const { return mpImplFont
->meUnderline
; }
713 FontLineStyle
Font::GetOverline() const { return mpImplFont
->meOverline
; }
714 FontStrikeout
Font::GetStrikeout() const { return mpImplFont
->meStrikeout
; }
715 FontEmphasisMark
Font::GetEmphasisMark() const { return mpImplFont
->meEmphasisMark
; }
716 bool Font::IsWordLineMode() const { return mpImplFont
->mbWordLine
; }
717 bool Font::IsSameInstance( const vcl::Font
& rFont
) const { return (mpImplFont
== rFont
.mpImplFont
); }
720 ImplFont::ImplFont() :
721 meWeight( WEIGHT_DONTKNOW
),
722 meFamily( FAMILY_DONTKNOW
),
723 mePitch( PITCH_DONTKNOW
),
724 meWidthType( WIDTH_DONTKNOW
),
725 meItalic( ITALIC_NONE
),
726 meAlign( ALIGN_TOP
),
727 meUnderline( LINESTYLE_NONE
),
728 meOverline( LINESTYLE_NONE
),
729 meStrikeout( STRIKEOUT_NONE
),
730 meRelief( FontRelief::NONE
),
731 meEmphasisMark( FontEmphasisMark::NONE
),
732 meKerning( FontKerning::NONE
),
733 meCharSet( RTL_TEXTENCODING_DONTKNOW
),
734 maLanguageTag( LANGUAGE_DONTKNOW
),
735 maCJKLanguageTag( LANGUAGE_DONTKNOW
),
736 mbSymbolFlag( false ),
738 mbConfigLookup( false ),
741 mbTransparent( true ),
742 maColor( COL_TRANSPARENT
),
743 maFillColor( COL_TRANSPARENT
),
749 ImplFont::ImplFont( const ImplFont
& rImplFont
) :
750 maFamilyName( rImplFont
.maFamilyName
),
751 maStyleName( rImplFont
.maStyleName
),
752 meWeight( rImplFont
.meWeight
),
753 meFamily( rImplFont
.meFamily
),
754 mePitch( rImplFont
.mePitch
),
755 meWidthType( rImplFont
.meWidthType
),
756 meItalic( rImplFont
.meItalic
),
757 meAlign( rImplFont
.meAlign
),
758 meUnderline( rImplFont
.meUnderline
),
759 meOverline( rImplFont
.meOverline
),
760 meStrikeout( rImplFont
.meStrikeout
),
761 meRelief( rImplFont
.meRelief
),
762 meEmphasisMark( rImplFont
.meEmphasisMark
),
763 meKerning( rImplFont
.meKerning
),
764 maAverageFontSize( rImplFont
.maAverageFontSize
),
765 meCharSet( rImplFont
.meCharSet
),
766 maLanguageTag( rImplFont
.maLanguageTag
),
767 maCJKLanguageTag( rImplFont
.maCJKLanguageTag
),
768 mbSymbolFlag( rImplFont
.mbSymbolFlag
),
769 mbOutline( rImplFont
.mbOutline
),
770 mbConfigLookup( rImplFont
.mbConfigLookup
),
771 mbShadow( rImplFont
.mbShadow
),
772 mbVertical( rImplFont
.mbVertical
),
773 mbTransparent( rImplFont
.mbTransparent
),
774 maColor( rImplFont
.maColor
),
775 maFillColor( rImplFont
.maFillColor
),
776 maMapNames( rImplFont
.maMapNames
),
777 mbWordLine( rImplFont
.mbWordLine
),
778 mnOrientation( rImplFont
.mnOrientation
),
779 mnQuality( rImplFont
.mnQuality
)
782 bool ImplFont::operator==( const ImplFont
& rOther
) const
784 // equality tests split up for easier debugging
785 if( (meWeight
!= rOther
.meWeight
)
786 || (meItalic
!= rOther
.meItalic
)
787 || (meFamily
!= rOther
.meFamily
)
788 || (mePitch
!= rOther
.mePitch
) )
791 if( (meCharSet
!= rOther
.meCharSet
)
792 || (maLanguageTag
!= rOther
.maLanguageTag
)
793 || (maCJKLanguageTag
!= rOther
.maCJKLanguageTag
)
794 || (meAlign
!= rOther
.meAlign
) )
797 if( (maAverageFontSize
!= rOther
.maAverageFontSize
)
798 || (mnOrientation
!= rOther
.mnOrientation
)
799 || (mbVertical
!= rOther
.mbVertical
) )
802 if( (maFamilyName
!= rOther
.maFamilyName
)
803 || (maStyleName
!= rOther
.maStyleName
) )
806 if( (maColor
!= rOther
.maColor
)
807 || (maFillColor
!= rOther
.maFillColor
) )
810 if( (meUnderline
!= rOther
.meUnderline
)
811 || (meOverline
!= rOther
.meOverline
)
812 || (meStrikeout
!= rOther
.meStrikeout
)
813 || (meRelief
!= rOther
.meRelief
)
814 || (meEmphasisMark
!= rOther
.meEmphasisMark
)
815 || (mbWordLine
!= rOther
.mbWordLine
)
816 || (mbOutline
!= rOther
.mbOutline
)
817 || (mbShadow
!= rOther
.mbShadow
)
818 || (meKerning
!= rOther
.meKerning
)
819 || (mbTransparent
!= rOther
.mbTransparent
) )
825 void ImplFont::AskConfig()
830 mbConfigLookup
= true;
832 // prepare the FontSubst configuration lookup
833 const utl::FontSubstConfiguration
& rFontSubst
= utl::FontSubstConfiguration::get();
836 OUString aFamilyName
;
837 ImplFontAttrs nType
= ImplFontAttrs::None
;
838 FontWeight eWeight
= WEIGHT_DONTKNOW
;
839 FontWidth eWidthType
= WIDTH_DONTKNOW
;
840 OUString aMapName
= GetEnglishSearchFontName( maFamilyName
);
842 utl::FontSubstConfiguration::getMapName( aMapName
,
843 aShortName
, aFamilyName
, eWeight
, eWidthType
, nType
);
845 // lookup the font name in the configuration
846 const utl::FontNameAttr
* pFontAttr
= rFontSubst
.getSubstInfo( aMapName
);
848 // if the direct lookup failed try again with an alias name
849 if ( !pFontAttr
&& (aShortName
!= aMapName
) )
850 pFontAttr
= rFontSubst
.getSubstInfo( aShortName
);
854 // the font was found in the configuration
855 if( meFamily
== FAMILY_DONTKNOW
)
857 if ( pFontAttr
->Type
& ImplFontAttrs::Serif
)
858 meFamily
= FAMILY_ROMAN
;
859 else if ( pFontAttr
->Type
& ImplFontAttrs::SansSerif
)
860 meFamily
= FAMILY_SWISS
;
861 else if ( pFontAttr
->Type
& ImplFontAttrs::Typewriter
)
862 meFamily
= FAMILY_MODERN
;
863 else if ( pFontAttr
->Type
& ImplFontAttrs::Italic
)
864 meFamily
= FAMILY_SCRIPT
;
865 else if ( pFontAttr
->Type
& ImplFontAttrs::Decorative
)
866 meFamily
= FAMILY_DECORATIVE
;
869 if( mePitch
== PITCH_DONTKNOW
)
871 if ( pFontAttr
->Type
& ImplFontAttrs::Fixed
)
872 mePitch
= PITCH_FIXED
;
876 // if some attributes are still unknown then use the FontSubst magic
877 if( meFamily
== FAMILY_DONTKNOW
)
879 if( nType
& ImplFontAttrs::Serif
)
880 meFamily
= FAMILY_ROMAN
;
881 else if( nType
& ImplFontAttrs::SansSerif
)
882 meFamily
= FAMILY_SWISS
;
883 else if( nType
& ImplFontAttrs::Typewriter
)
884 meFamily
= FAMILY_MODERN
;
885 else if( nType
& ImplFontAttrs::Italic
)
886 meFamily
= FAMILY_SCRIPT
;
887 else if( nType
& ImplFontAttrs::Decorative
)
888 meFamily
= FAMILY_DECORATIVE
;
891 if( GetWeight() == WEIGHT_DONTKNOW
)
892 SetWeight( eWeight
);
893 if( meWidthType
== WIDTH_DONTKNOW
)
894 meWidthType
= eWidthType
;
897 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */