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 "unotools/fontcfg.hxx"
22 #include "tools/stream.hxx"
23 #include "tools/vcompat.hxx"
24 #include "tools/debug.hxx"
25 #include <tools/gen.hxx>
27 #include "vcl/font.hxx"
29 #include "impfont.hxx"
30 #include "outfont.hxx"
33 #include <sal/macros.h>
39 Impl_Font::Impl_Font() :
40 maColor( COL_TRANSPARENT
),
41 maFillColor( COL_TRANSPARENT
),
42 maLanguageTag( LANGUAGE_DONTKNOW
),
43 maCJKLanguageTag( LANGUAGE_DONTKNOW
)
46 meCharSet
= RTL_TEXTENCODING_DONTKNOW
;
47 meFamily
= FAMILY_DONTKNOW
;
48 mePitch
= PITCH_DONTKNOW
;
50 meWeight
= WEIGHT_DONTKNOW
;
51 meWidthType
= WIDTH_DONTKNOW
;
52 meItalic
= ITALIC_NONE
;
53 meUnderline
= UNDERLINE_NONE
;
54 meOverline
= UNDERLINE_NONE
;
55 meStrikeout
= STRIKEOUT_NONE
;
56 meRelief
= RELIEF_NONE
;
57 meEmphasisMark
= EMPHASISMARK_NONE
;
59 mnKerning
= FontKerning::NONE
;
65 mbConfigLookup
= false;
68 Impl_Font::Impl_Font( const Impl_Font
& rImplFont
)
69 : maFamilyName( rImplFont
.maFamilyName
),
70 maStyleName( rImplFont
.maStyleName
),
71 maSize( rImplFont
.maSize
),
72 maColor( rImplFont
.maColor
),
73 maFillColor( rImplFont
.maFillColor
),
74 maLanguageTag( rImplFont
.maLanguageTag
),
75 maCJKLanguageTag( rImplFont
.maCJKLanguageTag
)
78 meCharSet
= rImplFont
.meCharSet
;
79 meFamily
= rImplFont
.meFamily
;
80 mePitch
= rImplFont
.mePitch
;
81 meAlign
= rImplFont
.meAlign
;
82 meWeight
= rImplFont
.meWeight
;
83 meWidthType
= rImplFont
.meWidthType
;
84 meItalic
= rImplFont
.meItalic
;
85 meUnderline
= rImplFont
.meUnderline
;
86 meOverline
= rImplFont
.meOverline
;
87 meStrikeout
= rImplFont
.meStrikeout
;
88 meRelief
= rImplFont
.meRelief
;
89 meEmphasisMark
= rImplFont
.meEmphasisMark
;
90 mnOrientation
= rImplFont
.mnOrientation
;
91 mnKerning
= rImplFont
.mnKerning
;
92 mbWordLine
= rImplFont
.mbWordLine
;
93 mbOutline
= rImplFont
.mbOutline
;
94 mbShadow
= rImplFont
.mbShadow
;
95 mbVertical
= rImplFont
.mbVertical
;
96 mbTransparent
= rImplFont
.mbTransparent
;
97 mbConfigLookup
= rImplFont
.mbConfigLookup
;
100 bool Impl_Font::operator==( const Impl_Font
& rOther
) const
102 // equality tests split up for easier debugging
103 if( (meWeight
!= rOther
.meWeight
)
104 || (meItalic
!= rOther
.meItalic
)
105 || (meFamily
!= rOther
.meFamily
)
106 || (mePitch
!= rOther
.mePitch
) )
109 if( (meCharSet
!= rOther
.meCharSet
)
110 || (maLanguageTag
!= rOther
.maLanguageTag
)
111 || (maCJKLanguageTag
!= rOther
.maCJKLanguageTag
)
112 || (meAlign
!= rOther
.meAlign
) )
115 if( (maSize
!= rOther
.maSize
)
116 || (mnOrientation
!= rOther
.mnOrientation
)
117 || (mbVertical
!= rOther
.mbVertical
) )
120 if( (maFamilyName
!= rOther
.maFamilyName
)
121 || (maStyleName
!= rOther
.maStyleName
) )
124 if( (maColor
!= rOther
.maColor
)
125 || (maFillColor
!= rOther
.maFillColor
) )
128 if( (meUnderline
!= rOther
.meUnderline
)
129 || (meOverline
!= rOther
.meOverline
)
130 || (meStrikeout
!= rOther
.meStrikeout
)
131 || (meRelief
!= rOther
.meRelief
)
132 || (meEmphasisMark
!= rOther
.meEmphasisMark
)
133 || (mbWordLine
!= rOther
.mbWordLine
)
134 || (mbOutline
!= rOther
.mbOutline
)
135 || (mbShadow
!= rOther
.mbShadow
)
136 || (mnKerning
!= rOther
.mnKerning
)
137 || (mbTransparent
!= rOther
.mbTransparent
) )
143 void Impl_Font::AskConfig()
148 mbConfigLookup
= true;
150 // prepare the FontSubst configuration lookup
151 const utl::FontSubstConfiguration
& rFontSubst
= utl::FontSubstConfiguration::get();
154 OUString aFamilyName
;
155 ImplFontAttrs nType
= ImplFontAttrs::None
;
156 FontWeight eWeight
= WEIGHT_DONTKNOW
;
157 FontWidth eWidthType
= WIDTH_DONTKNOW
;
158 OUString aMapName
= GetEnglishSearchFontName( maFamilyName
);
160 utl::FontSubstConfiguration::getMapName( aMapName
,
161 aShortName
, aFamilyName
, eWeight
, eWidthType
, nType
);
163 // lookup the font name in the configuration
164 const utl::FontNameAttr
* pFontAttr
= rFontSubst
.getSubstInfo( aMapName
);
166 // if the direct lookup failed try again with an alias name
167 if ( !pFontAttr
&& (aShortName
!= aMapName
) )
168 pFontAttr
= rFontSubst
.getSubstInfo( aShortName
);
172 // the font was found in the configuration
173 if( meFamily
== FAMILY_DONTKNOW
)
175 if ( pFontAttr
->Type
& ImplFontAttrs::Serif
)
176 meFamily
= FAMILY_ROMAN
;
177 else if ( pFontAttr
->Type
& ImplFontAttrs::SansSerif
)
178 meFamily
= FAMILY_SWISS
;
179 else if ( pFontAttr
->Type
& ImplFontAttrs::Typewriter
)
180 meFamily
= FAMILY_MODERN
;
181 else if ( pFontAttr
->Type
& ImplFontAttrs::Italic
)
182 meFamily
= FAMILY_SCRIPT
;
183 else if ( pFontAttr
->Type
& ImplFontAttrs::Decorative
)
184 meFamily
= FAMILY_DECORATIVE
;
187 if( mePitch
== PITCH_DONTKNOW
)
189 if ( pFontAttr
->Type
& ImplFontAttrs::Fixed
)
190 mePitch
= PITCH_FIXED
;
194 // if some attributes are still unknown then use the FontSubst magic
195 if( meFamily
== FAMILY_DONTKNOW
)
197 if( nType
& ImplFontAttrs::Serif
)
198 meFamily
= FAMILY_ROMAN
;
199 else if( nType
& ImplFontAttrs::SansSerif
)
200 meFamily
= FAMILY_SWISS
;
201 else if( nType
& ImplFontAttrs::Typewriter
)
202 meFamily
= FAMILY_MODERN
;
203 else if( nType
& ImplFontAttrs::Italic
)
204 meFamily
= FAMILY_SCRIPT
;
205 else if( nType
& ImplFontAttrs::Decorative
)
206 meFamily
= FAMILY_DECORATIVE
;
209 if( meWeight
== WEIGHT_DONTKNOW
)
211 if( meWidthType
== WIDTH_DONTKNOW
)
212 meWidthType
= eWidthType
;
215 void Font::MakeUnique()
217 // create a copy if others still reference it
218 if ( mpImplFont
->mnRefCount
!= 1 )
220 if ( mpImplFont
->mnRefCount
)
221 mpImplFont
->mnRefCount
--;
222 mpImplFont
= new Impl_Font( *mpImplFont
);
229 static Impl_Font aStaticImplFont
;
230 // RefCount is zero for static objects
231 aStaticImplFont
.mnRefCount
= 0;
232 mpImplFont
= &aStaticImplFont
;
235 Font::Font( const vcl::Font
& rFont
)
237 bool bRefIncrementable
= rFont
.mpImplFont
->mnRefCount
< ::std::numeric_limits
<sal_uInt32
>::max();
238 DBG_ASSERT( bRefIncrementable
, "Font: RefCount overflow" );
240 mpImplFont
= rFont
.mpImplFont
;
241 // do not count static objects (where RefCount is zero)
242 if ( mpImplFont
->mnRefCount
&& bRefIncrementable
)
243 mpImplFont
->mnRefCount
++;
246 Font::Font( const OUString
& rFamilyName
, const Size
& rSize
)
249 mpImplFont
= new Impl_Font
;
250 mpImplFont
->maFamilyName
= rFamilyName
;
251 mpImplFont
->maSize
= rSize
;
254 Font::Font( const OUString
& rFamilyName
, const OUString
& rStyleName
, const Size
& rSize
)
257 mpImplFont
= new Impl_Font
;
258 mpImplFont
->maFamilyName
= rFamilyName
;
259 mpImplFont
->maStyleName
= rStyleName
;
260 mpImplFont
->maSize
= rSize
;
263 Font::Font( FontFamily eFamily
, const Size
& rSize
)
266 mpImplFont
= new Impl_Font
;
267 mpImplFont
->meFamily
= eFamily
;
268 mpImplFont
->maSize
= rSize
;
274 // decrement reference counter and delete if last reference
275 // if the object is not static (Refcounter==0)
276 if ( mpImplFont
->mnRefCount
)
278 if ( mpImplFont
->mnRefCount
== 1 )
281 mpImplFont
->mnRefCount
--;
285 void Font::SetColor( const Color
& rColor
)
288 if( mpImplFont
->maColor
!= rColor
)
291 mpImplFont
->maColor
= rColor
;
295 void Font::SetFillColor( const Color
& rColor
)
299 mpImplFont
->maFillColor
= rColor
;
300 if ( rColor
.GetTransparency() )
301 mpImplFont
->mbTransparent
= true;
302 if (GetUnderline() == UNDERLINE_SINGLE
) {
303 SAL_INFO("vcl.gdi", "I'm setting a filling (from Font) of (" << rColor
.GetRed() << "," << rColor
.GetGreen() << "," << rColor
.GetBlue() << ")");
307 void Font::SetTransparent( bool bTransparent
)
310 if( mpImplFont
->mbTransparent
!= bTransparent
)
313 mpImplFont
->mbTransparent
= bTransparent
;
317 void Font::SetAlign( FontAlign eAlign
)
320 if( mpImplFont
->meAlign
!= eAlign
)
323 mpImplFont
->meAlign
= eAlign
;
327 void Font::SetName( const OUString
& rFamilyName
)
331 mpImplFont
->maFamilyName
= rFamilyName
;
334 void Font::SetStyleName( const OUString
& rStyleName
)
338 mpImplFont
->maStyleName
= rStyleName
;
341 void Font::SetSize( const Size
& rSize
)
344 if( mpImplFont
->maSize
!= rSize
)
347 mpImplFont
->maSize
= rSize
;
351 void Font::SetFamily( FontFamily eFamily
)
354 if( mpImplFont
->meFamily
!= eFamily
)
357 mpImplFont
->meFamily
= eFamily
;
361 void Font::SetCharSet( rtl_TextEncoding eCharSet
)
364 if( mpImplFont
->meCharSet
!= eCharSet
)
367 mpImplFont
->meCharSet
= eCharSet
;
371 void Font::SetLanguageTag( const LanguageTag
& rLanguageTag
)
374 if( mpImplFont
->maLanguageTag
!= rLanguageTag
)
377 mpImplFont
->maLanguageTag
= rLanguageTag
;
381 void Font::SetCJKContextLanguageTag( const LanguageTag
& rLanguageTag
)
384 if( mpImplFont
->maCJKLanguageTag
!= rLanguageTag
)
387 mpImplFont
->maCJKLanguageTag
= rLanguageTag
;
391 void Font::SetLanguage( LanguageType eLanguage
)
394 if( mpImplFont
->maLanguageTag
.getLanguageType( false) != eLanguage
)
397 mpImplFont
->maLanguageTag
.reset( eLanguage
);
401 void Font::SetCJKContextLanguage( LanguageType eLanguage
)
404 if( mpImplFont
->maCJKLanguageTag
.getLanguageType( false) != eLanguage
)
407 mpImplFont
->maCJKLanguageTag
.reset( eLanguage
);
411 void Font::SetPitch( FontPitch ePitch
)
414 if( mpImplFont
->mePitch
!= ePitch
)
417 mpImplFont
->mePitch
= ePitch
;
421 void Font::SetOrientation( short nOrientation
)
424 if( mpImplFont
->mnOrientation
!= nOrientation
)
427 mpImplFont
->mnOrientation
= nOrientation
;
431 void Font::SetVertical( bool bVertical
)
434 if( mpImplFont
->mbVertical
!= bVertical
)
437 mpImplFont
->mbVertical
= bVertical
;
441 void Font::SetKerning( FontKerning nKerning
)
444 if( mpImplFont
->mnKerning
!= nKerning
)
447 mpImplFont
->mnKerning
= nKerning
;
451 bool Font::IsKerning() const
453 return bool(mpImplFont
->mnKerning
& FontKerning::FontSpecific
);
456 void Font::SetWeight( FontWeight eWeight
)
459 if( mpImplFont
->meWeight
!= eWeight
)
462 mpImplFont
->meWeight
= eWeight
;
466 void Font::SetWidthType( FontWidth eWidth
)
469 if( mpImplFont
->meWidthType
!= eWidth
)
472 mpImplFont
->meWidthType
= eWidth
;
476 void Font::SetItalic( FontItalic eItalic
)
479 if( mpImplFont
->meItalic
!= eItalic
)
482 mpImplFont
->meItalic
= eItalic
;
486 void Font::SetOutline( bool bOutline
)
489 if( mpImplFont
->mbOutline
!= bOutline
)
492 mpImplFont
->mbOutline
= bOutline
;
496 void Font::SetShadow( bool bShadow
)
499 if( mpImplFont
->mbShadow
!= bShadow
)
502 mpImplFont
->mbShadow
= bShadow
;
506 void Font::SetUnderline( FontUnderline eUnderline
)
509 if( mpImplFont
->meUnderline
!= eUnderline
)
512 mpImplFont
->meUnderline
= eUnderline
;
516 void Font::SetOverline( FontUnderline eOverline
)
519 if( mpImplFont
->meOverline
!= eOverline
)
522 mpImplFont
->meOverline
= eOverline
;
526 void Font::SetStrikeout( FontStrikeout eStrikeout
)
529 if( mpImplFont
->meStrikeout
!= eStrikeout
)
532 mpImplFont
->meStrikeout
= eStrikeout
;
536 void Font::SetRelief( FontRelief eRelief
)
539 if( mpImplFont
->meRelief
!= eRelief
)
542 mpImplFont
->meRelief
= eRelief
;
546 void Font::SetEmphasisMark( FontEmphasisMark eEmphasisMark
)
549 if( mpImplFont
->meEmphasisMark
!= eEmphasisMark
)
552 mpImplFont
->meEmphasisMark
= eEmphasisMark
;
556 void Font::SetWordLineMode( bool bWordLine
)
559 if( mpImplFont
->mbWordLine
!= bWordLine
)
562 mpImplFont
->mbWordLine
= bWordLine
;
566 Font
& Font::operator=( const vcl::Font
& rFont
)
568 bool bRefIncrementable
= rFont
.mpImplFont
->mnRefCount
< ::std::numeric_limits
<sal_uInt32
>::max();
569 DBG_ASSERT( bRefIncrementable
, "Font: RefCount overflow" );
571 // Increment RefCount first, so that we can reference ourselves
572 // RefCount == 0 for static objects
573 if ( rFont
.mpImplFont
->mnRefCount
&& bRefIncrementable
)
574 rFont
.mpImplFont
->mnRefCount
++;
576 // If it's not static ImplData and if it's the last reference, delete it
577 // else decrement RefCount
578 if ( mpImplFont
->mnRefCount
)
580 if ( mpImplFont
->mnRefCount
== 1 )
583 mpImplFont
->mnRefCount
--;
586 mpImplFont
= rFont
.mpImplFont
;
591 bool Font::operator==( const vcl::Font
& rFont
) const
593 return mpImplFont
== rFont
.mpImplFont
|| *mpImplFont
== *rFont
.mpImplFont
;
596 void Font::Merge( const vcl::Font
& rFont
)
598 if ( !rFont
.GetName().isEmpty() )
600 SetName( rFont
.GetName() );
601 SetStyleName( rFont
.GetStyleName() );
602 SetCharSet( GetCharSet() );
603 SetLanguageTag( rFont
.GetLanguageTag() );
604 SetCJKContextLanguageTag( rFont
.GetCJKContextLanguageTag() );
605 // don't use access methods here, might lead to AskConfig(), if DONTKNOW
606 SetFamily( rFont
.mpImplFont
->meFamily
);
607 SetPitch( rFont
.mpImplFont
->mePitch
);
610 // don't use access methods here, might lead to AskConfig(), if DONTKNOW
611 if ( rFont
.mpImplFont
->meWeight
!= WEIGHT_DONTKNOW
)
612 SetWeight( rFont
.GetWeight() );
613 if ( rFont
.mpImplFont
->meItalic
!= ITALIC_DONTKNOW
)
614 SetItalic( rFont
.GetItalic() );
615 if ( rFont
.mpImplFont
->meWidthType
!= WIDTH_DONTKNOW
)
616 SetWidthType( rFont
.GetWidthType() );
618 if ( rFont
.GetSize().Height() )
619 SetSize( rFont
.GetSize() );
620 if ( rFont
.GetUnderline() != UNDERLINE_DONTKNOW
)
622 SetUnderline( rFont
.GetUnderline() );
623 SetWordLineMode( rFont
.IsWordLineMode() );
625 if ( rFont
.GetOverline() != UNDERLINE_DONTKNOW
)
627 SetOverline( rFont
.GetOverline() );
628 SetWordLineMode( rFont
.IsWordLineMode() );
630 if ( rFont
.GetStrikeout() != STRIKEOUT_DONTKNOW
)
632 SetStrikeout( rFont
.GetStrikeout() );
633 SetWordLineMode( rFont
.IsWordLineMode() );
637 SetOrientation( rFont
.GetOrientation() );
638 SetVertical( rFont
.IsVertical() );
639 SetEmphasisMark( rFont
.GetEmphasisMark() );
640 SetKerning( rFont
.IsKerning() ? FontKerning::FontSpecific
: FontKerning::NONE
);
641 SetOutline( rFont
.IsOutline() );
642 SetShadow( rFont
.IsShadow() );
643 SetRelief( rFont
.GetRelief() );
646 void Font::GetFontAttributes( ImplFontAttributes
& rAttrs
) const
648 rAttrs
.SetFamilyName( mpImplFont
->maFamilyName
);
649 rAttrs
.SetStyleName( mpImplFont
->maStyleName
);
650 rAttrs
.SetFamilyType( mpImplFont
->meFamily
);
651 rAttrs
.SetPitch( mpImplFont
->mePitch
);
652 rAttrs
.SetItalic( mpImplFont
->meItalic
);
653 rAttrs
.SetWeight( mpImplFont
->meWeight
);
654 rAttrs
.SetWidthType( WIDTH_DONTKNOW
);
655 rAttrs
.SetSymbolFlag( mpImplFont
->meCharSet
== RTL_TEXTENCODING_SYMBOL
);
658 SvStream
& ReadImpl_Font( SvStream
& rIStm
, Impl_Font
& rImpl_Font
)
660 VersionCompat
aCompat( rIStm
, StreamMode::READ
);
665 rImpl_Font
.maFamilyName
= rIStm
.ReadUniOrByteString(rIStm
.GetStreamCharSet());
666 rImpl_Font
.maStyleName
= rIStm
.ReadUniOrByteString(rIStm
.GetStreamCharSet());
667 ReadPair( rIStm
, rImpl_Font
.maSize
);
669 rIStm
.ReadUInt16( nTmp16
); rImpl_Font
.meCharSet
= (rtl_TextEncoding
) nTmp16
;
670 rIStm
.ReadUInt16( nTmp16
); rImpl_Font
.meFamily
= (FontFamily
) nTmp16
;
671 rIStm
.ReadUInt16( nTmp16
); rImpl_Font
.mePitch
= (FontPitch
) nTmp16
;
672 rIStm
.ReadUInt16( nTmp16
); rImpl_Font
.meWeight
= (FontWeight
) nTmp16
;
673 rIStm
.ReadUInt16( nTmp16
); rImpl_Font
.meUnderline
= (FontUnderline
) nTmp16
;
674 rIStm
.ReadUInt16( nTmp16
); rImpl_Font
.meStrikeout
= (FontStrikeout
) nTmp16
;
675 rIStm
.ReadUInt16( nTmp16
); rImpl_Font
.meItalic
= (FontItalic
) nTmp16
;
676 rIStm
.ReadUInt16( nTmp16
); rImpl_Font
.maLanguageTag
.reset( (LanguageType
) nTmp16
);
677 rIStm
.ReadUInt16( nTmp16
); rImpl_Font
.meWidthType
= (FontWidth
) nTmp16
;
679 rIStm
.ReadInt16( rImpl_Font
.mnOrientation
);
681 rIStm
.ReadCharAsBool( bTmp
); rImpl_Font
.mbWordLine
= bTmp
;
682 rIStm
.ReadCharAsBool( bTmp
); rImpl_Font
.mbOutline
= bTmp
;
683 rIStm
.ReadCharAsBool( bTmp
); rImpl_Font
.mbShadow
= bTmp
;
684 rIStm
.ReadUChar( nTmp8
); rImpl_Font
.mnKerning
= static_cast<FontKerning
>(nTmp8
);
686 if( aCompat
.GetVersion() >= 2 )
688 rIStm
.ReadUChar( nTmp8
); rImpl_Font
.meRelief
= (FontRelief
)nTmp8
;
689 rIStm
.ReadUInt16( nTmp16
); rImpl_Font
.maCJKLanguageTag
.reset( (LanguageType
)nTmp16
);
690 rIStm
.ReadCharAsBool( bTmp
); rImpl_Font
.mbVertical
= bTmp
;
691 rIStm
.ReadUInt16( nTmp16
); rImpl_Font
.meEmphasisMark
= (FontEmphasisMark
)nTmp16
;
693 if( aCompat
.GetVersion() >= 3 )
695 rIStm
.ReadUInt16( nTmp16
); rImpl_Font
.meOverline
= (FontUnderline
) nTmp16
;
698 // CJKContextLanguage
703 SvStream
& WriteImpl_Font( SvStream
& rOStm
, const Impl_Font
& rImpl_Font
)
705 VersionCompat
aCompat( rOStm
, StreamMode::WRITE
, 3 );
706 rOStm
.WriteUniOrByteString( rImpl_Font
.maFamilyName
, rOStm
.GetStreamCharSet() );
707 rOStm
.WriteUniOrByteString( rImpl_Font
.maStyleName
, rOStm
.GetStreamCharSet() );
708 WritePair( rOStm
, rImpl_Font
.maSize
);
710 rOStm
.WriteUInt16( GetStoreCharSet( rImpl_Font
.meCharSet
) );
711 rOStm
.WriteUInt16( rImpl_Font
.meFamily
);
712 rOStm
.WriteUInt16( rImpl_Font
.mePitch
);
713 rOStm
.WriteUInt16( rImpl_Font
.meWeight
);
714 rOStm
.WriteUInt16( rImpl_Font
.meUnderline
);
715 rOStm
.WriteUInt16( rImpl_Font
.meStrikeout
);
716 rOStm
.WriteUInt16( rImpl_Font
.meItalic
);
717 rOStm
.WriteUInt16( rImpl_Font
.maLanguageTag
.getLanguageType( false) );
718 rOStm
.WriteUInt16( rImpl_Font
.meWidthType
);
720 rOStm
.WriteInt16( rImpl_Font
.mnOrientation
);
722 rOStm
.WriteBool( rImpl_Font
.mbWordLine
);
723 rOStm
.WriteBool( rImpl_Font
.mbOutline
);
724 rOStm
.WriteBool( rImpl_Font
.mbShadow
);
725 rOStm
.WriteUChar( static_cast<sal_uInt8
>(rImpl_Font
.mnKerning
) );
728 rOStm
.WriteUChar( rImpl_Font
.meRelief
);
729 rOStm
.WriteUInt16( rImpl_Font
.maCJKLanguageTag
.getLanguageType( false) );
730 rOStm
.WriteBool( rImpl_Font
.mbVertical
);
731 rOStm
.WriteUInt16( rImpl_Font
.meEmphasisMark
);
734 rOStm
.WriteUInt16( rImpl_Font
.meOverline
);
739 SvStream
& ReadFont( SvStream
& rIStm
, vcl::Font
& rFont
)
742 return ReadImpl_Font( rIStm
, *rFont
.mpImplFont
);
745 SvStream
& WriteFont( SvStream
& rOStm
, const vcl::Font
& rFont
)
747 return WriteImpl_Font( rOStm
, *rFont
.mpImplFont
);
752 bool identifyTrueTypeFont( const void* i_pBuffer
, sal_uInt32 i_nSize
, Font
& o_rResult
)
754 bool bResult
= false;
755 TrueTypeFont
* pTTF
= NULL
;
756 if( OpenTTFontBuffer( i_pBuffer
, i_nSize
, 0, &pTTF
) == SF_OK
)
758 TTGlobalFontInfo aInfo
;
759 GetTTGlobalFontInfo( pTTF
, &aInfo
);
760 // most importantly: the family name
762 o_rResult
.SetName( aInfo
.ufamily
);
763 else if( aInfo
.family
)
764 o_rResult
.SetName( OStringToOUString( aInfo
.family
, RTL_TEXTENCODING_ASCII_US
) );
768 if( aInfo
.weight
< FW_EXTRALIGHT
)
769 o_rResult
.SetWeight( WEIGHT_THIN
);
770 else if( aInfo
.weight
< FW_LIGHT
)
771 o_rResult
.SetWeight( WEIGHT_ULTRALIGHT
);
772 else if( aInfo
.weight
< FW_NORMAL
)
773 o_rResult
.SetWeight( WEIGHT_LIGHT
);
774 else if( aInfo
.weight
< FW_MEDIUM
)
775 o_rResult
.SetWeight( WEIGHT_NORMAL
);
776 else if( aInfo
.weight
< FW_SEMIBOLD
)
777 o_rResult
.SetWeight( WEIGHT_MEDIUM
);
778 else if( aInfo
.weight
< FW_BOLD
)
779 o_rResult
.SetWeight( WEIGHT_SEMIBOLD
);
780 else if( aInfo
.weight
< FW_EXTRABOLD
)
781 o_rResult
.SetWeight( WEIGHT_BOLD
);
782 else if( aInfo
.weight
< FW_BLACK
)
783 o_rResult
.SetWeight( WEIGHT_ULTRABOLD
);
785 o_rResult
.SetWeight( WEIGHT_BLACK
);
788 o_rResult
.SetWeight( (aInfo
.macStyle
& 1) ? WEIGHT_BOLD
: WEIGHT_NORMAL
);
792 if( aInfo
.width
== FWIDTH_ULTRA_CONDENSED
)
793 o_rResult
.SetWidth( WIDTH_ULTRA_CONDENSED
);
794 else if( aInfo
.width
== FWIDTH_EXTRA_CONDENSED
)
795 o_rResult
.SetWidth( WIDTH_EXTRA_CONDENSED
);
796 else if( aInfo
.width
== FWIDTH_CONDENSED
)
797 o_rResult
.SetWidth( WIDTH_CONDENSED
);
798 else if( aInfo
.width
== FWIDTH_SEMI_CONDENSED
)
799 o_rResult
.SetWidth( WIDTH_SEMI_CONDENSED
);
800 else if( aInfo
.width
== FWIDTH_NORMAL
)
801 o_rResult
.SetWidth( WIDTH_NORMAL
);
802 else if( aInfo
.width
== FWIDTH_SEMI_EXPANDED
)
803 o_rResult
.SetWidth( WIDTH_SEMI_EXPANDED
);
804 else if( aInfo
.width
== FWIDTH_EXPANDED
)
805 o_rResult
.SetWidth( WIDTH_EXPANDED
);
806 else if( aInfo
.width
== FWIDTH_EXTRA_EXPANDED
)
807 o_rResult
.SetWidth( WIDTH_EXTRA_EXPANDED
);
808 else if( aInfo
.width
>= FWIDTH_ULTRA_EXPANDED
)
809 o_rResult
.SetWidth( WIDTH_ULTRA_EXPANDED
);
812 o_rResult
.SetItalic( (aInfo
.italicAngle
!= 0) ? ITALIC_NORMAL
: ITALIC_NONE
);
815 o_rResult
.SetPitch( (aInfo
.pitch
== 0) ? PITCH_VARIABLE
: PITCH_FIXED
);
818 if( aInfo
.usubfamily
)
819 o_rResult
.SetStyleName( OUString( aInfo
.usubfamily
) );
820 else if( aInfo
.subfamily
)
821 o_rResult
.SetStyleName( OUString::createFromAscii( aInfo
.subfamily
) );
831 struct WeightSearchEntry
837 bool operator<( const WeightSearchEntry
& rRight
) const
839 return rtl_str_compareIgnoreAsciiCase_WithLength( string
, string_len
, rRight
.string
, rRight
.string_len
) < 0;
844 { "black", 5, WEIGHT_BLACK
},
845 { "bold", 4, WEIGHT_BOLD
},
846 { "book", 4, WEIGHT_LIGHT
},
847 { "demi", 4, WEIGHT_SEMIBOLD
},
848 { "heavy", 5, WEIGHT_BLACK
},
849 { "light", 5, WEIGHT_LIGHT
},
850 { "medium", 6, WEIGHT_MEDIUM
},
851 { "regular", 7, WEIGHT_NORMAL
},
852 { "super", 5, WEIGHT_ULTRABOLD
},
853 { "thin", 4, WEIGHT_THIN
}
856 bool identifyType1Font( const char* i_pBuffer
, sal_uInt32 i_nSize
, Font
& o_rResult
)
858 bool bResult
= false;
859 // might be a type1, find eexec
860 const char* pStream
= i_pBuffer
;
861 const char* pExec
= "eexec";
862 const char* pExecPos
= std::search( pStream
, pStream
+i_nSize
, pExec
, pExec
+5 );
863 if( pExecPos
!= pStream
+i_nSize
)
865 // find /FamilyName entry
866 static const char* pFam
= "/FamilyName";
867 const char* pFamPos
= std::search( pStream
, pExecPos
, pFam
, pFam
+11 );
868 if( pFamPos
!= pExecPos
)
870 // extract the string value behind /FamilyName
871 const char* pOpen
= pFamPos
+11;
872 while( pOpen
< pExecPos
&& *pOpen
!= '(' )
874 const char* pClose
= pOpen
;
875 while( pClose
< pExecPos
&& *pClose
!= ')' )
877 if( pClose
- pOpen
> 1 )
879 o_rResult
.SetName( OStringToOUString( OString( pOpen
+1, pClose
-pOpen
-1 ), RTL_TEXTENCODING_ASCII_US
) );
883 // parse /ItalicAngle
884 static const char* pItalic
= "/ItalicAngle";
885 const char* pItalicPos
= std::search( pStream
, pExecPos
, pItalic
, pItalic
+12 );
886 if( pItalicPos
!= pExecPos
)
888 sal_Int32 nItalic
= rtl_str_toInt32( pItalicPos
+12, 10 );
889 o_rResult
.SetItalic( (nItalic
!= 0) ? ITALIC_NORMAL
: ITALIC_NONE
);
893 static const char* pWeight
= "/Weight";
894 const char* pWeightPos
= std::search( pStream
, pExecPos
, pWeight
, pWeight
+7 );
895 if( pWeightPos
!= pExecPos
)
897 // extract the string value behind /Weight
898 const char* pOpen
= pWeightPos
+7;
899 while( pOpen
< pExecPos
&& *pOpen
!= '(' )
901 const char* pClose
= pOpen
;
902 while( pClose
< pExecPos
&& *pClose
!= ')' )
904 if( pClose
- pOpen
> 1 )
906 WeightSearchEntry aEnt
;
907 aEnt
.string
= pOpen
+1;
908 aEnt
.string_len
= (pClose
-pOpen
)-1;
909 aEnt
.weight
= WEIGHT_NORMAL
;
910 const int nEnt
= SAL_N_ELEMENTS( weight_table
);
911 WeightSearchEntry
* pFound
= std::lower_bound( weight_table
, weight_table
+nEnt
, aEnt
);
912 if( pFound
!= (weight_table
+nEnt
) )
913 o_rResult
.SetWeight( pFound
->weight
);
917 // parse isFixedPitch
918 static const char* pFixed
= "/isFixedPitch";
919 const char* pFixedPos
= std::search( pStream
, pExecPos
, pFixed
, pFixed
+13 );
920 if( pFixedPos
!= pExecPos
)
923 while( pFixedPos
< pExecPos
-4 &&
924 ( *pFixedPos
== ' ' ||
925 *pFixedPos
== '\t' ||
926 *pFixedPos
== '\r' ||
927 *pFixedPos
== '\n' ) )
932 if( rtl_str_compareIgnoreAsciiCase_WithLength( pFixedPos
, 4, "true", 4 ) == 0 )
933 o_rResult
.SetPitch( PITCH_FIXED
);
935 o_rResult
.SetPitch( PITCH_VARIABLE
);
942 Font
Font::identifyFont( const void* i_pBuffer
, sal_uInt32 i_nSize
)
945 if( ! identifyTrueTypeFont( i_pBuffer
, i_nSize
, aResult
) )
947 const char* pStream
= static_cast<const char*>(i_pBuffer
);
948 if( pStream
&& i_nSize
> 100 &&
949 *pStream
== '%' && pStream
[1] == '!' )
951 identifyType1Font( pStream
, i_nSize
, aResult
);
958 // The inlines from the font.hxx header are now instantiated for pImpl-ification
959 const Color
& Font::GetColor() const { return mpImplFont
->maColor
; }
961 const Color
& Font::GetFillColor() const { return mpImplFont
->maFillColor
; }
963 bool Font::IsTransparent() const { return mpImplFont
->mbTransparent
; }
965 FontAlign
Font::GetAlign() const { return mpImplFont
->meAlign
; }
967 const OUString
& Font::GetName() const { return mpImplFont
->maFamilyName
; }
969 const OUString
& Font::GetStyleName() const { return mpImplFont
->maStyleName
; }
971 const Size
& Font::GetSize() const { return mpImplFont
->maSize
; }
973 void Font::SetHeight( long nHeight
) { SetSize( Size( mpImplFont
->maSize
.Width(), nHeight
) ); }
975 long Font::GetHeight() const { return mpImplFont
->maSize
.Height(); }
977 void Font::SetWidth( long nWidth
) { SetSize( Size( nWidth
, mpImplFont
->maSize
.Height() ) ); }
979 long Font::GetWidth() const { return mpImplFont
->maSize
.Width(); }
981 rtl_TextEncoding
Font::GetCharSet() const { return mpImplFont
->meCharSet
; }
983 const LanguageTag
& Font::GetLanguageTag() const { return mpImplFont
->maLanguageTag
; }
985 const LanguageTag
& Font::GetCJKContextLanguageTag() const { return mpImplFont
->maCJKLanguageTag
; }
987 LanguageType
Font::GetLanguage() const { return mpImplFont
->maLanguageTag
.getLanguageType( false); }
989 LanguageType
Font::GetCJKContextLanguage() const { return mpImplFont
->maCJKLanguageTag
.getLanguageType( false); }
991 short Font::GetOrientation() const { return mpImplFont
->mnOrientation
; }
993 bool Font::IsVertical() const { return mpImplFont
->mbVertical
; }
995 FontKerning
Font::GetKerning() const { return mpImplFont
->mnKerning
; }
997 FontPitch
Font::GetPitch() const { return mpImplFont
->GetPitch(); }
999 FontWeight
Font::GetWeight() const { return mpImplFont
->GetWeight(); }
1001 FontWidth
Font::GetWidthType() const { return mpImplFont
->GetWidthType(); }
1003 FontItalic
Font::GetItalic() const { return mpImplFont
->GetItalic(); }
1005 FontFamily
Font::GetFamily() const { return mpImplFont
->GetFamily(); }
1007 bool Font::IsOutline() const { return mpImplFont
->mbOutline
; }
1009 bool Font::IsShadow() const { return mpImplFont
->mbShadow
; }
1011 FontRelief
Font::GetRelief() const { return mpImplFont
->meRelief
; }
1013 FontUnderline
Font::GetUnderline() const { return mpImplFont
->meUnderline
; }
1015 FontUnderline
Font::GetOverline() const { return mpImplFont
->meOverline
; }
1017 FontStrikeout
Font::GetStrikeout() const { return mpImplFont
->meStrikeout
; }
1019 FontEmphasisMark
Font::GetEmphasisMark() const { return mpImplFont
->meEmphasisMark
; }
1021 bool Font::IsWordLineMode() const { return mpImplFont
->mbWordLine
; }
1023 bool Font::IsSameInstance( const vcl::Font
& rFont
) const { return (mpImplFont
== rFont
.mpImplFont
); }
1025 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */