1 /*************************************************************************
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
5 * Copyright 2008 by Sun Microsystems, Inc.
7 * OpenOffice.org - a multi-platform office productivity suite
9 * $RCSfile: font.cxx,v $
10 * $Revision: 1.19.134.1 $
12 * This file is part of OpenOffice.org.
14 * OpenOffice.org is free software: you can redistribute it and/or modify
15 * it under the terms of the GNU Lesser General Public License version 3
16 * only, as published by the Free Software Foundation.
18 * OpenOffice.org is distributed in the hope that it will be useful,
19 * but WITHOUT ANY WARRANTY; without even the implied warranty of
20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 * GNU Lesser General Public License version 3 for more details
22 * (a copy is included in the LICENSE file that accompanied this code).
24 * You should have received a copy of the GNU Lesser General Public License
25 * version 3 along with OpenOffice.org. If not, see
26 * <http://www.openoffice.org/license.html>
27 * for a copy of the LGPLv3 License.
29 ************************************************************************/
31 // MARKER(update_precomp.py): autogen include statement, do not remove
32 #include "precompiled_vcl.hxx"
36 #include "tools/stream.hxx"
37 #include "tools/vcompat.hxx"
38 #include "tools/debug.hxx"
39 #include "vcl/font.hxx"
40 #include "vcl/impfont.hxx"
41 #include "vcl/fontcfg.hxx"
42 #include "vcl/outdev.h" // just for ImplGetEnglishSearchFontName! TODO: move it
48 // =======================================================================
52 // -----------------------------------------------------------------------
54 Impl_Font::Impl_Font() :
55 maColor( COL_TRANSPARENT
),
56 maFillColor( COL_TRANSPARENT
)
59 meCharSet
= RTL_TEXTENCODING_DONTKNOW
;
60 meLanguage
= LANGUAGE_DONTKNOW
;
61 meCJKLanguage
= LANGUAGE_DONTKNOW
;
62 meFamily
= FAMILY_DONTKNOW
;
63 mePitch
= PITCH_DONTKNOW
;
65 meWeight
= WEIGHT_DONTKNOW
;
66 meWidthType
= WIDTH_DONTKNOW
;
67 meItalic
= ITALIC_NONE
;
68 meUnderline
= UNDERLINE_NONE
;
69 meOverline
= UNDERLINE_NONE
;
70 meStrikeout
= STRIKEOUT_NONE
;
71 meRelief
= RELIEF_NONE
;
72 meEmphasisMark
= EMPHASISMARK_NONE
;
80 mbConfigLookup
= false;
83 // -----------------------------------------------------------------------
85 Impl_Font::Impl_Font( const Impl_Font
& rImplFont
)
86 : maFamilyName( rImplFont
.maFamilyName
),
87 maStyleName( rImplFont
.maStyleName
),
88 maSize( rImplFont
.maSize
),
89 maColor( rImplFont
.maColor
),
90 maFillColor( rImplFont
.maFillColor
)
93 meCharSet
= rImplFont
.meCharSet
;
94 meLanguage
= rImplFont
.meLanguage
;
95 meCJKLanguage
= rImplFont
.meCJKLanguage
;
96 meFamily
= rImplFont
.meFamily
;
97 mePitch
= rImplFont
.mePitch
;
98 meAlign
= rImplFont
.meAlign
;
99 meWeight
= rImplFont
.meWeight
;
100 meWidthType
= rImplFont
.meWidthType
;
101 meItalic
= rImplFont
.meItalic
;
102 meUnderline
= rImplFont
.meUnderline
;
103 meOverline
= rImplFont
.meOverline
;
104 meStrikeout
= rImplFont
.meStrikeout
;
105 meRelief
= rImplFont
.meRelief
;
106 meEmphasisMark
= rImplFont
.meEmphasisMark
;
107 mnOrientation
= rImplFont
.mnOrientation
;
108 mnKerning
= rImplFont
.mnKerning
;
109 mbWordLine
= rImplFont
.mbWordLine
;
110 mbOutline
= rImplFont
.mbOutline
;
111 mbShadow
= rImplFont
.mbShadow
;
112 mbVertical
= rImplFont
.mbVertical
;
113 mbTransparent
= rImplFont
.mbTransparent
;
114 mbConfigLookup
= rImplFont
.mbConfigLookup
;
117 // -----------------------------------------------------------------------
119 bool Impl_Font::operator==( const Impl_Font
& rOther
) const
121 // equality tests split up for easier debugging
122 if( (meWeight
!= rOther
.meWeight
)
123 || (meItalic
!= rOther
.meItalic
)
124 || (meFamily
!= rOther
.meFamily
)
125 || (mePitch
!= rOther
.mePitch
) )
128 if( (meCharSet
!= rOther
.meCharSet
)
129 || (meLanguage
!= rOther
.meLanguage
)
130 || (meCJKLanguage
!= rOther
.meCJKLanguage
)
131 || (meAlign
!= rOther
.meAlign
) )
134 if( (maSize
!= rOther
.maSize
)
135 || (mnOrientation
!= rOther
.mnOrientation
)
136 || (mbVertical
!= rOther
.mbVertical
) )
139 if( (maFamilyName
!= rOther
.maFamilyName
)
140 || (maStyleName
!= rOther
.maStyleName
) )
143 if( (maColor
!= rOther
.maColor
)
144 || (maFillColor
!= rOther
.maFillColor
) )
147 if( (meUnderline
!= rOther
.meUnderline
)
148 || (meOverline
!= rOther
.meOverline
)
149 || (meStrikeout
!= rOther
.meStrikeout
)
150 || (meRelief
!= rOther
.meRelief
)
151 || (meEmphasisMark
!= rOther
.meEmphasisMark
)
152 || (mbWordLine
!= rOther
.mbWordLine
)
153 || (mbOutline
!= rOther
.mbOutline
)
154 || (mbShadow
!= rOther
.mbShadow
)
155 || (mnKerning
!= rOther
.mnKerning
)
156 || (mbTransparent
!= rOther
.mbTransparent
) )
162 // -----------------------------------------------------------------------
164 void Impl_Font::AskConfig()
169 mbConfigLookup
= true;
171 // prepare the FontSubst configuration lookup
172 const vcl::FontSubstConfiguration
* pFontSubst
= vcl::FontSubstConfiguration::get();
177 FontWeight eWeight
= WEIGHT_DONTKNOW
;
178 FontWidth eWidthType
= WIDTH_DONTKNOW
;
179 String aMapName
= maFamilyName
;
180 ImplGetEnglishSearchFontName( aMapName
);
181 vcl::FontSubstConfiguration::getMapName( aMapName
,
182 aShortName
, aFamilyName
, eWeight
, eWidthType
, nType
);
184 // lookup the font name in the configuration
185 const vcl::FontNameAttr
* pFontAttr
= pFontSubst
->getSubstInfo( aMapName
);
187 // if the direct lookup failed try again with an alias name
188 if ( !pFontAttr
&& (aShortName
!= aMapName
) )
189 pFontAttr
= pFontSubst
->getSubstInfo( aShortName
);
193 // the font was found in the configuration
194 if( meFamily
== FAMILY_DONTKNOW
)
196 if ( pFontAttr
->Type
& IMPL_FONT_ATTR_SERIF
)
197 meFamily
= FAMILY_ROMAN
;
198 else if ( pFontAttr
->Type
& IMPL_FONT_ATTR_SANSSERIF
)
199 meFamily
= FAMILY_SWISS
;
200 else if ( pFontAttr
->Type
& IMPL_FONT_ATTR_TYPEWRITER
)
201 meFamily
= FAMILY_MODERN
;
202 else if ( pFontAttr
->Type
& IMPL_FONT_ATTR_ITALIC
)
203 meFamily
= FAMILY_SCRIPT
;
204 else if ( pFontAttr
->Type
& IMPL_FONT_ATTR_DECORATIVE
)
205 meFamily
= FAMILY_DECORATIVE
;
208 if( mePitch
== PITCH_DONTKNOW
)
210 if ( pFontAttr
->Type
& IMPL_FONT_ATTR_FIXED
)
211 mePitch
= PITCH_FIXED
;
215 // if some attributes are still unknown then use the FontSubst magic
216 if( meFamily
== FAMILY_DONTKNOW
)
218 if( nType
& IMPL_FONT_ATTR_SERIF
)
219 meFamily
= FAMILY_ROMAN
;
220 else if( nType
& IMPL_FONT_ATTR_SANSSERIF
)
221 meFamily
= FAMILY_SWISS
;
222 else if( nType
& IMPL_FONT_ATTR_TYPEWRITER
)
223 meFamily
= FAMILY_MODERN
;
224 else if( nType
& IMPL_FONT_ATTR_ITALIC
)
225 meFamily
= FAMILY_SCRIPT
;
226 else if( nType
& IMPL_FONT_ATTR_DECORATIVE
)
227 meFamily
= FAMILY_DECORATIVE
;
230 if( meWeight
== WEIGHT_DONTKNOW
)
232 if( meWidthType
== WIDTH_DONTKNOW
)
233 meWidthType
= eWidthType
;
236 // =======================================================================
238 void Font::MakeUnique()
240 // create a copy if others still reference it
241 if ( mpImplFont
->mnRefCount
!= 1 )
243 if ( mpImplFont
->mnRefCount
)
244 mpImplFont
->mnRefCount
--;
245 mpImplFont
= new Impl_Font( *mpImplFont
);
249 // -----------------------------------------------------------------------
253 DBG_CTOR( Font
, NULL
);
255 static Impl_Font aStaticImplFont
;
256 // RefCount is zero for static objects
257 aStaticImplFont
.mnRefCount
= 0;
258 mpImplFont
= &aStaticImplFont
;
261 // -----------------------------------------------------------------------
263 Font::Font( const Font
& rFont
)
265 DBG_CTOR( Font
, NULL
);
266 DBG_CHKOBJ( &rFont
, Font
, NULL
);
267 DBG_ASSERT( rFont
.mpImplFont
->mnRefCount
< 0xFFFE, "Font: RefCount overflow" );
269 mpImplFont
= rFont
.mpImplFont
;
270 // do not count static objects (where RefCount is zero)
271 if ( mpImplFont
->mnRefCount
)
272 mpImplFont
->mnRefCount
++;
275 // -----------------------------------------------------------------------
277 Font::Font( const String
& rFamilyName
, const Size
& rSize
)
279 DBG_CTOR( Font
, NULL
);
281 mpImplFont
= new Impl_Font
;
282 mpImplFont
->maFamilyName
= rFamilyName
;
283 mpImplFont
->maSize
= rSize
;
286 // -----------------------------------------------------------------------
288 Font::Font( const String
& rFamilyName
, const String
& rStyleName
, const Size
& rSize
)
290 DBG_CTOR( Font
, NULL
);
292 mpImplFont
= new Impl_Font
;
293 mpImplFont
->maFamilyName
= rFamilyName
;
294 mpImplFont
->maStyleName
= rStyleName
;
295 mpImplFont
->maSize
= rSize
;
298 // -----------------------------------------------------------------------
300 Font::Font( FontFamily eFamily
, const Size
& rSize
)
302 DBG_CTOR( Font
, NULL
);
304 mpImplFont
= new Impl_Font
;
305 mpImplFont
->meFamily
= eFamily
;
306 mpImplFont
->maSize
= rSize
;
309 // -----------------------------------------------------------------------
313 DBG_DTOR( Font
, NULL
);
315 // decrement reference counter and delete if last reference
316 // if the object is not static (Refcounter==0)
317 if ( mpImplFont
->mnRefCount
)
319 if ( mpImplFont
->mnRefCount
== 1 )
322 mpImplFont
->mnRefCount
--;
326 // -----------------------------------------------------------------------
328 void Font::SetColor( const Color
& rColor
)
330 DBG_CHKTHIS( Font
, NULL
);
332 if( mpImplFont
->maColor
!= rColor
)
335 mpImplFont
->maColor
= rColor
;
339 // -----------------------------------------------------------------------
341 void Font::SetFillColor( const Color
& rColor
)
343 DBG_CHKTHIS( Font
, NULL
);
346 mpImplFont
->maFillColor
= rColor
;
347 if ( rColor
.GetTransparency() )
348 mpImplFont
->mbTransparent
= true;
351 // -----------------------------------------------------------------------
353 void Font::SetTransparent( BOOL bTransparent
)
355 DBG_CHKTHIS( Font
, NULL
);
357 if( mpImplFont
->mbTransparent
!= bTransparent
)
360 mpImplFont
->mbTransparent
= bTransparent
;
364 // -----------------------------------------------------------------------
366 void Font::SetAlign( FontAlign eAlign
)
368 DBG_CHKTHIS( Font
, NULL
);
370 if( mpImplFont
->meAlign
!= eAlign
)
373 mpImplFont
->meAlign
= eAlign
;
377 // -----------------------------------------------------------------------
379 void Font::SetName( const String
& rFamilyName
)
381 DBG_CHKTHIS( Font
, NULL
);
384 mpImplFont
->maFamilyName
= rFamilyName
;
387 // -----------------------------------------------------------------------
389 void Font::SetStyleName( const String
& rStyleName
)
391 DBG_CHKTHIS( Font
, NULL
);
394 mpImplFont
->maStyleName
= rStyleName
;
397 // -----------------------------------------------------------------------
399 void Font::SetSize( const Size
& rSize
)
401 DBG_CHKTHIS( Font
, NULL
);
403 if( mpImplFont
->maSize
!= rSize
)
406 mpImplFont
->maSize
= rSize
;
410 // -----------------------------------------------------------------------
412 void Font::SetFamily( FontFamily eFamily
)
414 DBG_CHKTHIS( Font
, NULL
);
416 if( mpImplFont
->meFamily
!= eFamily
)
419 mpImplFont
->meFamily
= eFamily
;
423 // -----------------------------------------------------------------------
425 void Font::SetCharSet( CharSet eCharSet
)
427 DBG_CHKTHIS( Font
, NULL
);
429 if( mpImplFont
->meCharSet
!= eCharSet
)
432 mpImplFont
->meCharSet
= eCharSet
;
436 // -----------------------------------------------------------------------
438 void Font::SetLanguage( LanguageType eLanguage
)
440 DBG_CHKTHIS( Font
, NULL
);
442 if( mpImplFont
->meLanguage
!= eLanguage
)
445 mpImplFont
->meLanguage
= eLanguage
;
449 // -----------------------------------------------------------------------
451 void Font::SetCJKContextLanguage( LanguageType eLanguage
)
453 DBG_CHKTHIS( Font
, NULL
);
455 if( mpImplFont
->meCJKLanguage
!= eLanguage
)
458 mpImplFont
->meCJKLanguage
= eLanguage
;
462 // -----------------------------------------------------------------------
464 void Font::SetPitch( FontPitch ePitch
)
466 DBG_CHKTHIS( Font
, NULL
);
468 if( mpImplFont
->mePitch
!= ePitch
)
471 mpImplFont
->mePitch
= ePitch
;
475 // -----------------------------------------------------------------------
477 void Font::SetOrientation( short nOrientation
)
479 DBG_CHKTHIS( Font
, NULL
);
481 if( mpImplFont
->mnOrientation
!= nOrientation
)
484 mpImplFont
->mnOrientation
= nOrientation
;
488 // -----------------------------------------------------------------------
490 void Font::SetVertical( BOOL bVertical
)
492 DBG_CHKTHIS( Font
, NULL
);
494 if( mpImplFont
->mbVertical
!= bVertical
)
497 mpImplFont
->mbVertical
= bVertical
;
501 // -----------------------------------------------------------------------
503 void Font::SetKerning( FontKerning nKerning
)
505 DBG_CHKTHIS( Font
, NULL
);
507 if( mpImplFont
->mnKerning
!= nKerning
)
510 mpImplFont
->mnKerning
= nKerning
;
514 // -----------------------------------------------------------------------
516 BOOL
Font::IsKerning() const
518 return (mpImplFont
->mnKerning
& KERNING_FONTSPECIFIC
) != 0;
521 // -----------------------------------------------------------------------
523 void Font::SetWeight( FontWeight eWeight
)
525 DBG_CHKTHIS( Font
, NULL
);
527 if( mpImplFont
->meWeight
!= eWeight
)
530 mpImplFont
->meWeight
= eWeight
;
534 // -----------------------------------------------------------------------
536 void Font::SetWidthType( FontWidth eWidth
)
538 DBG_CHKTHIS( Font
, NULL
);
540 if( mpImplFont
->meWidthType
!= eWidth
)
543 mpImplFont
->meWidthType
= eWidth
;
547 // -----------------------------------------------------------------------
549 void Font::SetItalic( FontItalic eItalic
)
551 DBG_CHKTHIS( Font
, NULL
);
553 if( mpImplFont
->meItalic
!= eItalic
)
556 mpImplFont
->meItalic
= eItalic
;
560 // -----------------------------------------------------------------------
562 void Font::SetOutline( BOOL bOutline
)
564 DBG_CHKTHIS( Font
, NULL
);
566 if( mpImplFont
->mbOutline
!= bOutline
)
569 mpImplFont
->mbOutline
= bOutline
;
573 // -----------------------------------------------------------------------
575 void Font::SetShadow( BOOL bShadow
)
577 DBG_CHKTHIS( Font
, NULL
);
579 if( mpImplFont
->mbShadow
!= bShadow
)
582 mpImplFont
->mbShadow
= bShadow
;
586 // -----------------------------------------------------------------------
588 void Font::SetUnderline( FontUnderline eUnderline
)
590 DBG_CHKTHIS( Font
, NULL
);
592 if( mpImplFont
->meUnderline
!= eUnderline
)
595 mpImplFont
->meUnderline
= eUnderline
;
599 // -----------------------------------------------------------------------
601 void Font::SetOverline( FontUnderline eOverline
)
603 DBG_CHKTHIS( Font
, NULL
);
605 if( mpImplFont
->meOverline
!= eOverline
)
608 mpImplFont
->meOverline
= eOverline
;
612 // -----------------------------------------------------------------------
614 void Font::SetStrikeout( FontStrikeout eStrikeout
)
616 DBG_CHKTHIS( Font
, NULL
);
618 if( mpImplFont
->meStrikeout
!= eStrikeout
)
621 mpImplFont
->meStrikeout
= eStrikeout
;
625 // -----------------------------------------------------------------------
627 void Font::SetRelief( FontRelief eRelief
)
629 DBG_CHKTHIS( Font
, NULL
);
631 if( mpImplFont
->meRelief
!= eRelief
)
634 mpImplFont
->meRelief
= eRelief
;
638 // -----------------------------------------------------------------------
640 void Font::SetEmphasisMark( FontEmphasisMark eEmphasisMark
)
642 DBG_CHKTHIS( Font
, NULL
);
644 if( mpImplFont
->meEmphasisMark
!= eEmphasisMark
)
647 mpImplFont
->meEmphasisMark
= eEmphasisMark
;
651 // -----------------------------------------------------------------------
653 void Font::SetWordLineMode( BOOL bWordLine
)
655 DBG_CHKTHIS( Font
, NULL
);
657 if( mpImplFont
->mbWordLine
!= bWordLine
)
660 mpImplFont
->mbWordLine
= bWordLine
;
664 // -----------------------------------------------------------------------
666 Font
& Font::operator=( const Font
& rFont
)
668 DBG_CHKTHIS( Font
, NULL
);
669 DBG_CHKOBJ( &rFont
, Font
, NULL
);
670 DBG_ASSERT( rFont
.mpImplFont
->mnRefCount
< 0xFFFE, "Font: RefCount overflow" );
672 // Zuerst Referenzcounter erhoehen, damit man sich selbst zuweisen kann
673 // RefCount == 0 fuer statische Objekte
674 if ( rFont
.mpImplFont
->mnRefCount
)
675 rFont
.mpImplFont
->mnRefCount
++;
677 // Wenn es keine statischen ImplDaten sind, dann loeschen, wenn es
678 // die letzte Referenz ist, sonst Referenzcounter decrementieren
679 if ( mpImplFont
->mnRefCount
)
681 if ( mpImplFont
->mnRefCount
== 1 )
684 mpImplFont
->mnRefCount
--;
687 mpImplFont
= rFont
.mpImplFont
;
692 // -----------------------------------------------------------------------
694 BOOL
Font::operator==( const Font
& rFont
) const
696 DBG_CHKTHIS( Font
, NULL
);
697 DBG_CHKOBJ( &rFont
, Font
, NULL
);
699 if( mpImplFont
== rFont
.mpImplFont
)
701 if( *mpImplFont
== *rFont
.mpImplFont
)
707 // -----------------------------------------------------------------------
709 void Font::Merge( const Font
& rFont
)
711 if ( rFont
.GetName().Len() )
713 SetName( rFont
.GetName() );
714 SetStyleName( rFont
.GetStyleName() );
715 SetCharSet( GetCharSet() );
716 SetLanguage( rFont
.GetLanguage() );
717 SetCJKContextLanguage( rFont
.GetCJKContextLanguage() );
718 // don't use access methods here, might lead to AskConfig(), if DONTKNOW
719 SetFamily( rFont
.mpImplFont
->meFamily
);
720 SetPitch( rFont
.mpImplFont
->mePitch
);
723 // don't use access methods here, might lead to AskConfig(), if DONTKNOW
724 if ( rFont
.mpImplFont
->meWeight
!= WEIGHT_DONTKNOW
)
725 SetWeight( rFont
.GetWeight() );
726 if ( rFont
.mpImplFont
->meItalic
!= ITALIC_DONTKNOW
)
727 SetItalic( rFont
.GetItalic() );
728 if ( rFont
.mpImplFont
->meWidthType
!= WIDTH_DONTKNOW
)
729 SetWidthType( rFont
.GetWidthType() );
732 if ( rFont
.GetSize().Height() )
733 SetSize( rFont
.GetSize() );
734 if ( rFont
.GetUnderline() != UNDERLINE_DONTKNOW
)
736 SetUnderline( rFont
.GetUnderline() );
737 SetWordLineMode( rFont
.IsWordLineMode() );
739 if ( rFont
.GetOverline() != UNDERLINE_DONTKNOW
)
741 SetOverline( rFont
.GetOverline() );
742 SetWordLineMode( rFont
.IsWordLineMode() );
744 if ( rFont
.GetStrikeout() != STRIKEOUT_DONTKNOW
)
746 SetStrikeout( rFont
.GetStrikeout() );
747 SetWordLineMode( rFont
.IsWordLineMode() );
751 SetOrientation( rFont
.GetOrientation() );
752 SetVertical( rFont
.IsVertical() );
753 SetEmphasisMark( rFont
.GetEmphasisMark() );
754 SetKerning( rFont
.IsKerning() );
755 SetOutline( rFont
.IsOutline() );
756 SetShadow( rFont
.IsShadow() );
757 SetRelief( rFont
.GetRelief() );
760 void Font::GetFontAttributes( ImplFontAttributes
& rAttrs
) const
762 // #i56788# Use members directly, don't risc config access.
763 rAttrs
.maName
= mpImplFont
->maFamilyName
;
764 rAttrs
.maStyleName
= mpImplFont
->maStyleName
;
765 rAttrs
.meFamily
= mpImplFont
->meFamily
;
766 rAttrs
.mePitch
= mpImplFont
->mePitch
;
767 rAttrs
.meItalic
= mpImplFont
->meItalic
;
768 rAttrs
.meWeight
= mpImplFont
->meWeight
;
769 rAttrs
.meWidthType
= WIDTH_DONTKNOW
;
770 rAttrs
.mbSymbolFlag
= (mpImplFont
->meCharSet
== RTL_TEXTENCODING_SYMBOL
);
774 // -----------------------------------------------------------------------
776 SvStream
& operator>>( SvStream
& rIStm
, Impl_Font
& rImpl_Font
)
778 VersionCompat
aCompat( rIStm
, STREAM_READ
);
783 rIStm
.ReadByteString( rImpl_Font
.maFamilyName
, rIStm
.GetStreamCharSet() );
784 rIStm
.ReadByteString( rImpl_Font
.maStyleName
, rIStm
.GetStreamCharSet() );
785 rIStm
>> rImpl_Font
.maSize
;
787 rIStm
>> nTmp16
; rImpl_Font
.meCharSet
= (rtl_TextEncoding
) nTmp16
;
788 rIStm
>> nTmp16
; rImpl_Font
.meFamily
= (FontFamily
) nTmp16
;
789 rIStm
>> nTmp16
; rImpl_Font
.mePitch
= (FontPitch
) nTmp16
;
790 rIStm
>> nTmp16
; rImpl_Font
.meWeight
= (FontWeight
) nTmp16
;
791 rIStm
>> nTmp16
; rImpl_Font
.meUnderline
= (FontUnderline
) nTmp16
;
792 rIStm
>> nTmp16
; rImpl_Font
.meStrikeout
= (FontStrikeout
) nTmp16
;
793 rIStm
>> nTmp16
; rImpl_Font
.meItalic
= (FontItalic
) nTmp16
;
794 rIStm
>> nTmp16
; rImpl_Font
.meLanguage
= (LanguageType
) nTmp16
;
795 rIStm
>> nTmp16
; rImpl_Font
.meWidthType
= (FontWidth
) nTmp16
;
797 rIStm
>> rImpl_Font
.mnOrientation
;
799 rIStm
>> bTmp
; rImpl_Font
.mbWordLine
= bTmp
;
800 rIStm
>> bTmp
; rImpl_Font
.mbOutline
= bTmp
;
801 rIStm
>> bTmp
; rImpl_Font
.mbShadow
= bTmp
;
802 rIStm
>> nTmp8
; rImpl_Font
.mnKerning
= nTmp8
;
804 if( aCompat
.GetVersion() >= 2 )
806 rIStm
>> nTmp8
; rImpl_Font
.meRelief
= (FontRelief
)nTmp8
;
807 rIStm
>> nTmp16
; rImpl_Font
.meCJKLanguage
= (LanguageType
)nTmp16
;
808 rIStm
>> bTmp
; rImpl_Font
.mbVertical
= bTmp
;
809 rIStm
>> nTmp16
; rImpl_Font
.meEmphasisMark
= (FontEmphasisMark
)nTmp16
;
811 if( aCompat
.GetVersion() >= 3 )
813 rIStm
>> nTmp16
; rImpl_Font
.meOverline
= (FontUnderline
) nTmp16
;
816 // CJKContextLanguage
821 // -----------------------------------------------------------------------
823 SvStream
& operator<<( SvStream
& rOStm
, const Impl_Font
& rImpl_Font
)
825 VersionCompat
aCompat( rOStm
, STREAM_WRITE
, 3 );
826 rOStm
.WriteByteString( rImpl_Font
.maFamilyName
, rOStm
.GetStreamCharSet() );
827 rOStm
.WriteByteString( rImpl_Font
.maStyleName
, rOStm
.GetStreamCharSet() );
828 rOStm
<< rImpl_Font
.maSize
;
830 rOStm
<< (UINT16
) GetStoreCharSet( rImpl_Font
.meCharSet
);
831 rOStm
<< (UINT16
) rImpl_Font
.meFamily
;
832 rOStm
<< (UINT16
) rImpl_Font
.mePitch
;
833 rOStm
<< (UINT16
) rImpl_Font
.meWeight
;
834 rOStm
<< (UINT16
) rImpl_Font
.meUnderline
;
835 rOStm
<< (UINT16
) rImpl_Font
.meStrikeout
;
836 rOStm
<< (UINT16
) rImpl_Font
.meItalic
;
837 rOStm
<< (UINT16
) rImpl_Font
.meLanguage
;
838 rOStm
<< (UINT16
) rImpl_Font
.meWidthType
;
840 rOStm
<< rImpl_Font
.mnOrientation
;
842 rOStm
<< (BOOL
) rImpl_Font
.mbWordLine
;
843 rOStm
<< (BOOL
) rImpl_Font
.mbOutline
;
844 rOStm
<< (BOOL
) rImpl_Font
.mbShadow
;
845 rOStm
<< (BYTE
) rImpl_Font
.mnKerning
;
848 rOStm
<< (BYTE
) rImpl_Font
.meRelief
;
849 rOStm
<< (UINT16
) rImpl_Font
.meCJKLanguage
;
850 rOStm
<< (BOOL
) rImpl_Font
.mbVertical
;
851 rOStm
<< (UINT16
) rImpl_Font
.meEmphasisMark
;
854 rOStm
<< (UINT16
) rImpl_Font
.meOverline
;
859 // -----------------------------------------------------------------------
861 SvStream
& operator>>( SvStream
& rIStm
, Font
& rFont
)
864 return( rIStm
>> *rFont
.mpImplFont
);
867 // -----------------------------------------------------------------------
869 SvStream
& operator<<( SvStream
& rOStm
, const Font
& rFont
)
871 return( rOStm
<< *rFont
.mpImplFont
);
874 // -----------------------------------------------------------------------
877 bool identifyTrueTypeFont( const void* i_pBuffer
, sal_uInt32 i_nSize
, Font
& o_rResult
)
879 bool bResult
= false;
880 // FIXME: This is HACK. We do not build psprint's part on aqua...
881 // How to solve this?
883 TrueTypeFont
* pTTF
= NULL
;
884 if( OpenTTFontBuffer( const_cast<void*>(i_pBuffer
), i_nSize
, 0, &pTTF
) == SF_OK
)
886 TTGlobalFontInfo aInfo
;
887 GetTTGlobalFontInfo( pTTF
, &aInfo
);
888 // most important: the family name
890 o_rResult
.SetName( aInfo
.ufamily
);
891 else if( aInfo
.family
)
892 o_rResult
.SetName( rtl::OStringToOUString( aInfo
.family
, RTL_TEXTENCODING_ASCII_US
) );
896 if( aInfo
.weight
< FW_EXTRALIGHT
)
897 o_rResult
.SetWeight( WEIGHT_THIN
);
898 else if( aInfo
.weight
< FW_LIGHT
)
899 o_rResult
.SetWeight( WEIGHT_ULTRALIGHT
);
900 else if( aInfo
.weight
< FW_NORMAL
)
901 o_rResult
.SetWeight( WEIGHT_LIGHT
);
902 else if( aInfo
.weight
< FW_MEDIUM
)
903 o_rResult
.SetWeight( WEIGHT_NORMAL
);
904 else if( aInfo
.weight
< FW_SEMIBOLD
)
905 o_rResult
.SetWeight( WEIGHT_MEDIUM
);
906 else if( aInfo
.weight
< FW_BOLD
)
907 o_rResult
.SetWeight( WEIGHT_SEMIBOLD
);
908 else if( aInfo
.weight
< FW_EXTRABOLD
)
909 o_rResult
.SetWeight( WEIGHT_BOLD
);
910 else if( aInfo
.weight
< FW_BLACK
)
911 o_rResult
.SetWeight( WEIGHT_ULTRABOLD
);
913 o_rResult
.SetWeight( WEIGHT_BLACK
);
916 o_rResult
.SetWeight( (aInfo
.macStyle
& 1) ? WEIGHT_BOLD
: WEIGHT_NORMAL
);
920 if( aInfo
.width
== FWIDTH_ULTRA_CONDENSED
)
921 o_rResult
.SetWidth( WIDTH_ULTRA_CONDENSED
);
922 else if( aInfo
.width
== FWIDTH_EXTRA_CONDENSED
)
923 o_rResult
.SetWidth( WIDTH_EXTRA_CONDENSED
);
924 else if( aInfo
.width
== FWIDTH_CONDENSED
)
925 o_rResult
.SetWidth( WIDTH_CONDENSED
);
926 else if( aInfo
.width
== FWIDTH_SEMI_CONDENSED
)
927 o_rResult
.SetWidth( WIDTH_SEMI_CONDENSED
);
928 else if( aInfo
.width
== FWIDTH_NORMAL
)
929 o_rResult
.SetWidth( WIDTH_NORMAL
);
930 else if( aInfo
.width
== FWIDTH_SEMI_EXPANDED
)
931 o_rResult
.SetWidth( WIDTH_SEMI_EXPANDED
);
932 else if( aInfo
.width
== FWIDTH_EXPANDED
)
933 o_rResult
.SetWidth( WIDTH_EXPANDED
);
934 else if( aInfo
.width
== FWIDTH_EXTRA_EXPANDED
)
935 o_rResult
.SetWidth( WIDTH_EXTRA_EXPANDED
);
936 else if( aInfo
.width
>= FWIDTH_ULTRA_EXPANDED
)
937 o_rResult
.SetWidth( WIDTH_ULTRA_EXPANDED
);
940 o_rResult
.SetItalic( (aInfo
.italicAngle
!= 0) ? ITALIC_NORMAL
: ITALIC_NONE
);
943 o_rResult
.SetPitch( (aInfo
.pitch
== 0) ? PITCH_VARIABLE
: PITCH_FIXED
);
946 if( aInfo
.usubfamily
)
947 o_rResult
.SetStyleName( rtl::OUString( aInfo
.usubfamily
) );
948 else if( aInfo
.subfamily
)
949 o_rResult
.SetStyleName( rtl::OUString::createFromAscii( aInfo
.subfamily
) );
960 struct WeightSearchEntry
966 bool operator<( const WeightSearchEntry
& rRight
) const
968 return rtl_str_compareIgnoreAsciiCase_WithLength( string
, string_len
, rRight
.string
, rRight
.string_len
) < 0;
973 { "black", 5, WEIGHT_BLACK
},
974 { "bold", 4, WEIGHT_BOLD
},
975 { "book", 4, WEIGHT_LIGHT
},
976 { "demi", 4, WEIGHT_SEMIBOLD
},
977 { "heavy", 5, WEIGHT_BLACK
},
978 { "light", 5, WEIGHT_LIGHT
},
979 { "medium", 6, WEIGHT_MEDIUM
},
980 { "regular", 7, WEIGHT_NORMAL
},
981 { "super", 5, WEIGHT_ULTRABOLD
},
982 { "thin", 4, WEIGHT_THIN
}
985 bool identifyType1Font( const char* i_pBuffer
, sal_uInt32 i_nSize
, Font
& o_rResult
)
987 bool bResult
= false;
988 // might be a type1, find eexec
989 const char* pStream
= i_pBuffer
;
990 const char* pExec
= "eexec";
991 const char* pExecPos
= std::search( pStream
, pStream
+i_nSize
, pExec
, pExec
+5 );
992 if( pExecPos
!= pStream
+i_nSize
)
994 // find /FamilyName entry
995 static const char* pFam
= "/FamilyName";
996 const char* pFamPos
= std::search( pStream
, pExecPos
, pFam
, pFam
+11 );
997 if( pFamPos
!= pExecPos
)
999 // extract the string value behind /FamilyName
1000 const char* pOpen
= pFamPos
+11;
1001 while( pOpen
< pExecPos
&& *pOpen
!= '(' )
1003 const char* pClose
= pOpen
;
1004 while( pClose
< pExecPos
&& *pClose
!= ')' )
1006 if( pClose
- pOpen
> 1 )
1008 o_rResult
.SetName( rtl::OStringToOUString( rtl::OString( pOpen
+1, pClose
-pOpen
-1 ), RTL_TEXTENCODING_ASCII_US
) );
1012 // parse /ItalicAngle
1013 static const char* pItalic
= "/ItalicAngle";
1014 const char* pItalicPos
= std::search( pStream
, pExecPos
, pItalic
, pItalic
+12 );
1015 if( pItalicPos
!= pExecPos
)
1017 sal_Int32 nItalic
= rtl_str_toInt32( pItalicPos
+12, 10 );
1018 o_rResult
.SetItalic( (nItalic
!= 0) ? ITALIC_NORMAL
: ITALIC_NONE
);
1022 static const char* pWeight
= "/Weight";
1023 const char* pWeightPos
= std::search( pStream
, pExecPos
, pWeight
, pWeight
+7 );
1024 if( pWeightPos
!= pExecPos
)
1026 // extract the string value behind /Weight
1027 const char* pOpen
= pWeightPos
+7;
1028 while( pOpen
< pExecPos
&& *pOpen
!= '(' )
1030 const char* pClose
= pOpen
;
1031 while( pClose
< pExecPos
&& *pClose
!= ')' )
1033 if( pClose
- pOpen
> 1 )
1035 WeightSearchEntry aEnt
;
1036 aEnt
.string
= pOpen
+1;
1037 aEnt
.string_len
= (pClose
-pOpen
)-1;
1038 aEnt
.weight
= WEIGHT_NORMAL
;
1039 const int nEnt
= sizeof( weight_table
) / sizeof( weight_table
[0] );
1040 WeightSearchEntry
* pFound
= std::lower_bound( weight_table
, weight_table
+nEnt
, aEnt
);
1041 if( pFound
!= (weight_table
+nEnt
) )
1042 o_rResult
.SetWeight( pFound
->weight
);
1046 // parse isFixedPitch
1047 static const char* pFixed
= "/isFixedPitch";
1048 const char* pFixedPos
= std::search( pStream
, pExecPos
, pFixed
, pFixed
+13 );
1049 if( pFixedPos
!= pExecPos
)
1052 while( pFixedPos
< pExecPos
-4 &&
1053 ( *pFixedPos
== ' ' ||
1054 *pFixedPos
== '\t' ||
1055 *pFixedPos
== '\r' ||
1056 *pFixedPos
== '\n' ) )
1060 // find "true" value
1061 if( rtl_str_compareIgnoreAsciiCase_WithLength( pFixedPos
, 4, "true", 4 ) == 0 )
1062 o_rResult
.SetPitch( PITCH_FIXED
);
1064 o_rResult
.SetPitch( PITCH_VARIABLE
);
1071 Font
Font::identifyFont( const void* i_pBuffer
, sal_uInt32 i_nSize
)
1074 if( ! identifyTrueTypeFont( i_pBuffer
, i_nSize
, aResult
) )
1076 const char* pStream
= reinterpret_cast<const char*>(i_pBuffer
);
1077 if( pStream
&& i_nSize
> 100 &&
1078 *pStream
== '%' && pStream
[1] == '!' )
1080 identifyType1Font( pStream
, i_nSize
, aResult
);
1087 // the inlines from the font.hxx header are now instantiated for pImpl-ification
1089 const Color
& Font::GetColor() const { return mpImplFont
->maColor
; }
1090 const Color
& Font::GetFillColor() const { return mpImplFont
->maFillColor
; }
1091 BOOL
Font::IsTransparent() const { return mpImplFont
->mbTransparent
; }
1092 FontAlign
Font::GetAlign() const { return mpImplFont
->meAlign
; }
1093 const String
& Font::GetName() const { return mpImplFont
->maFamilyName
; }
1094 const String
& Font::GetStyleName() const { return mpImplFont
->maStyleName
; }
1095 const Size
& Font::GetSize() const { return mpImplFont
->maSize
; }
1096 void Font::SetHeight( long nHeight
) { SetSize( Size( mpImplFont
->maSize
.Width(), nHeight
) ); }
1097 long Font::GetHeight() const { return mpImplFont
->maSize
.Height(); }
1098 void Font::SetWidth( long nWidth
) { SetSize( Size( nWidth
, mpImplFont
->maSize
.Height() ) ); }
1099 long Font::GetWidth() const { return mpImplFont
->maSize
.Width(); }
1100 rtl_TextEncoding
Font::GetCharSet() const { return mpImplFont
->meCharSet
; }
1101 LanguageType
Font::GetLanguage() const { return mpImplFont
->meLanguage
; }
1102 LanguageType
Font::GetCJKContextLanguage() const { return mpImplFont
->meCJKLanguage
; }
1103 short Font::GetOrientation() const { return mpImplFont
->mnOrientation
; }
1104 BOOL
Font::IsVertical() const { return mpImplFont
->mbVertical
; }
1105 FontKerning
Font::GetKerning() const { return mpImplFont
->mnKerning
; }
1106 FontPitch
Font::GetPitch() const { return mpImplFont
->GetPitch(); }
1107 FontWeight
Font::GetWeight() const { return mpImplFont
->GetWeight(); }
1108 FontWidth
Font::GetWidthType() const { return mpImplFont
->GetWidthType(); }
1109 FontItalic
Font::GetItalic() const { return mpImplFont
->GetItalic(); }
1110 FontFamily
Font::GetFamily() const { return mpImplFont
->GetFamily(); }
1111 BOOL
Font::IsOutline() const { return mpImplFont
->mbOutline
; }
1112 BOOL
Font::IsShadow() const { return mpImplFont
->mbShadow
; }
1113 FontRelief
Font::GetRelief() const { return mpImplFont
->meRelief
; }
1114 FontUnderline
Font::GetUnderline() const { return mpImplFont
->meUnderline
; }
1115 FontUnderline
Font::GetOverline() const { return mpImplFont
->meOverline
; }
1116 FontStrikeout
Font::GetStrikeout() const { return mpImplFont
->meStrikeout
; }
1117 FontEmphasisMark
Font::GetEmphasisMark() const { return mpImplFont
->meEmphasisMark
; }
1118 BOOL
Font::IsWordLineMode() const { return mpImplFont
->mbWordLine
; }
1119 BOOL
Font::IsSameInstance( const Font
& rFont
) const { return (mpImplFont
== rFont
.mpImplFont
); }