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 * This file is part of OpenOffice.org.
11 * OpenOffice.org is free software: you can redistribute it and/or modify
12 * it under the terms of the GNU Lesser General Public License version 3
13 * only, as published by the Free Software Foundation.
15 * OpenOffice.org is distributed in the hope that it will be useful,
16 * but WITHOUT ANY WARRANTY; without even the implied warranty of
17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 * GNU Lesser General Public License version 3 for more details
19 * (a copy is included in the LICENSE file that accompanied this code).
21 * You should have received a copy of the GNU Lesser General Public License
22 * version 3 along with OpenOffice.org. If not, see
23 * <http://www.openoffice.org/license.html>
24 * for a copy of the LGPLv3 License.
26 ************************************************************************/
28 // MARKER(update_precomp.py): autogen include statement, do not remove
29 #include "precompiled_vcl.hxx"
31 #include <boost/assert.hpp>
36 #include "saldata.hxx"
37 #include "vcl/svapp.hxx"
38 #include "salatsuifontutils.hxx"
40 // we have to get the font attributes from the name table
41 // since neither head's macStyle nor OS/2's panose are easily available
42 // during font enumeration. macStyle bits would be not sufficient anyway
43 // and SFNT fonts on Mac usually do not contain an OS/2 table.
44 static void UpdateAttributesFromPSName( const String
& rPSName
, ImplDevFontAttributes
& rDFA
)
46 ByteString
aPSName( rPSName
, RTL_TEXTENCODING_UTF8
);
47 aPSName
.ToLowerAscii();
49 // TODO: use a multi-string ignore-case matcher once it becomes available
50 if( (aPSName
.Search("regular") != STRING_NOTFOUND
)
51 || (aPSName
.Search("normal") != STRING_NOTFOUND
)
52 || (aPSName
.Search("roman") != STRING_NOTFOUND
)
53 || (aPSName
.Search("medium") != STRING_NOTFOUND
)
54 || (aPSName
.Search("plain") != STRING_NOTFOUND
)
55 || (aPSName
.Search("standard") != STRING_NOTFOUND
)
56 || (aPSName
.Search("std") != STRING_NOTFOUND
) )
58 rDFA
.meWidthType
= WIDTH_NORMAL
;
59 rDFA
.meWeight
= WEIGHT_NORMAL
;
60 rDFA
.meItalic
= ITALIC_NONE
;
63 // heuristics for font weight
64 if (aPSName
.Search("extrablack") != STRING_NOTFOUND
)
65 rDFA
.meWeight
= WEIGHT_BLACK
;
66 else if (aPSName
.Search("black") != STRING_NOTFOUND
)
67 rDFA
.meWeight
= WEIGHT_BLACK
;
68 //else if (aPSName.Search("book") != STRING_NOTFOUND)
69 // rDFA.meWeight = WEIGHT_SEMIBOLD;
70 else if( (aPSName
.Search("semibold") != STRING_NOTFOUND
)
71 || (aPSName
.Search("smbd") != STRING_NOTFOUND
))
72 rDFA
.meWeight
= WEIGHT_SEMIBOLD
;
73 else if (aPSName
.Search("ultrabold") != STRING_NOTFOUND
)
74 rDFA
.meWeight
= WEIGHT_ULTRABOLD
;
75 else if (aPSName
.Search("extrabold") != STRING_NOTFOUND
)
76 rDFA
.meWeight
= WEIGHT_BLACK
;
77 else if( (aPSName
.Search("bold") != STRING_NOTFOUND
)
78 || (aPSName
.Search("-bd") != STRING_NOTFOUND
))
79 rDFA
.meWeight
= WEIGHT_BOLD
;
80 else if (aPSName
.Search("extralight") != STRING_NOTFOUND
)
81 rDFA
.meWeight
= WEIGHT_ULTRALIGHT
;
82 else if (aPSName
.Search("ultralight") != STRING_NOTFOUND
)
83 rDFA
.meWeight
= WEIGHT_ULTRALIGHT
;
84 else if (aPSName
.Search("light") != STRING_NOTFOUND
)
85 rDFA
.meWeight
= WEIGHT_LIGHT
;
86 else if (aPSName
.Search("thin") != STRING_NOTFOUND
)
87 rDFA
.meWeight
= WEIGHT_THIN
;
88 else if (aPSName
.Search("-w3") != STRING_NOTFOUND
)
89 rDFA
.meWeight
= WEIGHT_LIGHT
;
90 else if (aPSName
.Search("-w4") != STRING_NOTFOUND
)
91 rDFA
.meWeight
= WEIGHT_SEMILIGHT
;
92 else if (aPSName
.Search("-w5") != STRING_NOTFOUND
)
93 rDFA
.meWeight
= WEIGHT_NORMAL
;
94 else if (aPSName
.Search("-w6") != STRING_NOTFOUND
)
95 rDFA
.meWeight
= WEIGHT_SEMIBOLD
;
96 else if (aPSName
.Search("-w7") != STRING_NOTFOUND
)
97 rDFA
.meWeight
= WEIGHT_BOLD
;
98 else if (aPSName
.Search("-w8") != STRING_NOTFOUND
)
99 rDFA
.meWeight
= WEIGHT_ULTRABOLD
;
100 else if (aPSName
.Search("-w9") != STRING_NOTFOUND
)
101 rDFA
.meWeight
= WEIGHT_BLACK
;
103 // heuristics for font slant
104 if( (aPSName
.Search("italic") != STRING_NOTFOUND
)
105 || (aPSName
.Search(" ital") != STRING_NOTFOUND
)
106 || (aPSName
.Search("cursive") != STRING_NOTFOUND
)
107 || (aPSName
.Search("-it") != STRING_NOTFOUND
)
108 || (aPSName
.Search("lightit") != STRING_NOTFOUND
)
109 || (aPSName
.Search("mediumit") != STRING_NOTFOUND
)
110 || (aPSName
.Search("boldit") != STRING_NOTFOUND
)
111 || (aPSName
.Search("cnit") != STRING_NOTFOUND
)
112 || (aPSName
.Search("bdcn") != STRING_NOTFOUND
)
113 || (aPSName
.Search("bdit") != STRING_NOTFOUND
)
114 || (aPSName
.Search("condit") != STRING_NOTFOUND
)
115 || (aPSName
.Search("bookit") != STRING_NOTFOUND
)
116 || (aPSName
.Search("blackit") != STRING_NOTFOUND
) )
117 rDFA
.meItalic
= ITALIC_NORMAL
;
118 if( (aPSName
.Search("oblique") != STRING_NOTFOUND
)
119 || (aPSName
.Search("inclined") != STRING_NOTFOUND
)
120 || (aPSName
.Search("slanted") != STRING_NOTFOUND
) )
121 rDFA
.meItalic
= ITALIC_OBLIQUE
;
123 // heuristics for font width
124 if( (aPSName
.Search("condensed") != STRING_NOTFOUND
)
125 || (aPSName
.Search("-cond") != STRING_NOTFOUND
)
126 || (aPSName
.Search("boldcond") != STRING_NOTFOUND
)
127 || (aPSName
.Search("boldcn") != STRING_NOTFOUND
)
128 || (aPSName
.Search("cnit") != STRING_NOTFOUND
) )
129 rDFA
.meWidthType
= WIDTH_CONDENSED
;
130 else if (aPSName
.Search("narrow") != STRING_NOTFOUND
)
131 rDFA
.meWidthType
= WIDTH_SEMI_CONDENSED
;
132 else if (aPSName
.Search("expanded") != STRING_NOTFOUND
)
133 rDFA
.meWidthType
= WIDTH_EXPANDED
;
134 else if (aPSName
.Search("wide") != STRING_NOTFOUND
)
135 rDFA
.meWidthType
= WIDTH_EXPANDED
;
137 // heuristics for font pitch
138 if( (aPSName
.Search("mono") != STRING_NOTFOUND
)
139 || (aPSName
.Search("courier") != STRING_NOTFOUND
)
140 || (aPSName
.Search("monaco") != STRING_NOTFOUND
)
141 || (aPSName
.Search("typewriter") != STRING_NOTFOUND
) )
142 rDFA
.mePitch
= PITCH_FIXED
;
144 // heuristics for font family type
145 if( (aPSName
.Search("script") != STRING_NOTFOUND
)
146 || (aPSName
.Search("chancery") != STRING_NOTFOUND
)
147 || (aPSName
.Search("zapfino") != STRING_NOTFOUND
))
148 rDFA
.meFamily
= FAMILY_SCRIPT
;
149 else if( (aPSName
.Search("comic") != STRING_NOTFOUND
)
150 || (aPSName
.Search("outline") != STRING_NOTFOUND
)
151 || (aPSName
.Search("pinpoint") != STRING_NOTFOUND
) )
152 rDFA
.meFamily
= FAMILY_DECORATIVE
;
153 else if( (aPSName
.Search("sans") != STRING_NOTFOUND
)
154 || (aPSName
.Search("arial") != STRING_NOTFOUND
) )
155 rDFA
.meFamily
= FAMILY_SWISS
;
156 else if( (aPSName
.Search("roman") != STRING_NOTFOUND
)
157 || (aPSName
.Search("times") != STRING_NOTFOUND
) )
158 rDFA
.meFamily
= FAMILY_ROMAN
;
160 // heuristics for codepoint semantic
161 if( (aPSName
.Search("symbol") != STRING_NOTFOUND
)
162 || (aPSName
.Search("dings") != STRING_NOTFOUND
)
163 || (aPSName
.Search("dingbats") != STRING_NOTFOUND
)
164 || (aPSName
.Search("ornaments") != STRING_NOTFOUND
)
165 || (aPSName
.Search("embellishments") != STRING_NOTFOUND
) )
166 rDFA
.mbSymbolFlag
= true;
168 // #i100020# special heuristic for names with single-char styles
169 // NOTE: we are checking name that hasn't been lower-cased
170 if( rPSName
.Len() > 3 )
172 int i
= rPSName
.Len();
173 sal_Unicode c
= rPSName
.GetChar( --i
);
174 if( c
== 'C' ) { // "capitals"
175 rDFA
.meFamily
= FAMILY_DECORATIVE
;
176 c
= rPSName
.GetChar( --i
);
178 if( c
== 'O' ) { // CFF-based OpenType
179 c
= rPSName
.GetChar( --i
);
181 if( c
== 'I' ) { // "italic"
182 rDFA
.meItalic
= ITALIC_NORMAL
;
183 c
= rPSName
.GetChar( --i
);
185 if( c
== 'B' ) // "bold"
186 rDFA
.meWeight
= WEIGHT_BOLD
;
187 if( c
== 'C' ) // "capitals"
188 rDFA
.meFamily
= FAMILY_DECORATIVE
;
189 // TODO: check that all single-char styles have been resolved?
193 // -----------------------------------------------------------------------
195 static bool GetDevFontAttributes( ATSUFontID nFontID
, ImplDevFontAttributes
& rDFA
)
197 // all ATSU fonts are device fonts that can be directly rotated
198 rDFA
.mbOrientation
= true;
199 rDFA
.mbDevice
= true;
202 // reset the attributes
203 rDFA
.meFamily
= FAMILY_DONTKNOW
;
204 rDFA
.mePitch
= PITCH_VARIABLE
;
205 rDFA
.meWidthType
= WIDTH_NORMAL
;
206 rDFA
.meWeight
= WEIGHT_NORMAL
;
207 rDFA
.meItalic
= ITALIC_NONE
;
208 rDFA
.mbSymbolFlag
= false;
210 // all scalable fonts on this platform are subsettable
211 rDFA
.mbSubsettable
= true;
212 rDFA
.mbEmbeddable
= false;
213 // TODO: these members are needed only for our X11 platform targets
214 rDFA
.meAntiAlias
= ANTIALIAS_DONTKNOW
;
215 rDFA
.meEmbeddedBitmap
= EMBEDDEDBITMAP_DONTKNOW
;
217 // prepare iterating over all name strings of the font
218 ItemCount nFontNameCount
= 0;
219 OSStatus rc
= ATSUCountFontNames( nFontID
, &nFontNameCount
);
222 int nBestNameValue
= 0;
223 int nBestStyleValue
= 0;
224 FontLanguageCode eBestLangCode
= 0;
225 const FontLanguageCode eUILangCode
= Application::GetSettings().GetUILanguage();
226 typedef std::vector
<char> NameBuffer
;
227 NameBuffer
aNameBuffer( 256 );
229 // iterate over all available name strings of the font
230 for( ItemCount nNameIndex
= 0; nNameIndex
< nFontNameCount
; ++nNameIndex
)
232 ByteCount nNameLength
= 0;
234 FontNameCode eFontNameCode
;
235 FontPlatformCode eFontNamePlatform
;
236 FontScriptCode eFontNameScript
;
237 FontLanguageCode eFontNameLanguage
;
238 rc
= ATSUGetIndFontName( nFontID
, nNameIndex
, 0, NULL
,
239 &nNameLength
, &eFontNameCode
, &eFontNamePlatform
, &eFontNameScript
, &eFontNameLanguage
);
243 // ignore non-interesting name entries
244 if( (eFontNameCode
!= kFontFamilyName
)
245 && (eFontNameCode
!= kFontStyleName
)
246 && (eFontNameCode
!= kFontPostscriptName
) )
249 // heuristic to find the most common font name
250 // prefering default language names or even better the names matching to the UI language
251 int nNameValue
= (eFontNameLanguage
==eUILangCode
) ? 0 : ((eFontNameLanguage
==0) ? -10 : -20);
252 rtl_TextEncoding eEncoding
= RTL_TEXTENCODING_UNICODE
;
253 const int nPlatformEncoding
= ((int)eFontNamePlatform
<< 8) + (int)eFontNameScript
;
254 switch( nPlatformEncoding
)
256 case 0x000: nNameValue
+= 23; break; // Unicode 1.0
257 case 0x001: nNameValue
+= 24; break; // Unicode 1.1
258 case 0x002: nNameValue
+= 25; break; // iso10646_1993
259 case 0x003: nNameValue
+= 26; break; // UCS-2
260 case 0x301: nNameValue
+= 27; break; // Win UCS-2
262 case 0x30A: nNameValue
+= 0; // Win-UCS-4
263 eEncoding
= RTL_TEXTENCODING_UCS4
;
265 case 0x100: nNameValue
+= 21; // Mac Roman
266 eEncoding
= RTL_TEXTENCODING_APPLE_ROMAN
;
268 case 0x300: nNameValue
= 0; // Win Symbol encoded name!
269 rDFA
.mbSymbolFlag
= true; // (often seen for symbol fonts)
271 default: nNameValue
= 0; // ignore other encodings
275 // ignore name entries with no useful encoding
276 if( nNameValue
<= 0 )
278 if( nNameLength
>= aNameBuffer
.size() )
281 // get the encoded name
282 aNameBuffer
.reserve( nNameLength
+1 ); // extra byte helps for debugging
283 rc
= ATSUGetIndFontName( nFontID
, nNameIndex
, nNameLength
, &aNameBuffer
[0],
284 &nNameLength
, &eFontNameCode
, &eFontNamePlatform
, &eFontNameScript
, &eFontNameLanguage
);
288 // convert to unicode name
289 UniString aUtf16Name
;
290 if( eEncoding
== RTL_TEXTENCODING_UNICODE
) // we are just interested in UTF16 encoded names
291 aUtf16Name
= UniString( (const sal_Unicode
*)&aNameBuffer
[0], nNameLength
/2 );
292 else if( eEncoding
== RTL_TEXTENCODING_UCS4
)
293 aUtf16Name
= UniString(); // TODO
294 else // assume the non-unicode encoded names are byte encoded
295 aUtf16Name
= UniString( &aNameBuffer
[0], nNameLength
, eEncoding
);
297 // ignore empty strings
298 if( aUtf16Name
.Len() <= 0 )
301 // handle the name depending on its namecode
302 switch( eFontNameCode
)
304 case kFontFamilyName
:
305 // ignore font names starting with '.'
306 if( aUtf16Name
.GetChar(0) == '.' )
308 else if( rDFA
.maName
.Len() )
310 // even if a family name is not the one we are looking for
311 // it is still useful as a font name alternative
312 if( rDFA
.maMapNames
.Len() )
313 rDFA
.maMapNames
+= ';';
314 rDFA
.maMapNames
+= (nBestNameValue
< nNameValue
) ? rDFA
.maName
: aUtf16Name
;
316 if( nBestNameValue
< nNameValue
)
318 // get the best family name
319 nBestNameValue
= nNameValue
;
320 eBestLangCode
= eFontNameLanguage
;
321 rDFA
.maName
= aUtf16Name
;
325 // get a style name matching to the family name
326 if( nBestStyleValue
< nNameValue
)
328 nBestStyleValue
= nNameValue
;
329 rDFA
.maStyleName
= aUtf16Name
;
332 case kFontPostscriptName
:
333 // use the postscript name to get some useful info
334 UpdateAttributesFromPSName( aUtf16Name
, rDFA
);
337 // TODO: use other name entries too?
342 #if 0 // multiple-master fonts are mostly obsolete nowadays
343 // if we still want to support them this should probably be done one frame higher
344 ItemCount nMaxInstances
= 0;
345 rc
= ATSUCountFontInstances ( nFontID
, &nMaxInstances
);
346 for( ItemCount nInstanceIndex
= 0; nInstanceIndex
< nMaxInstances
; ++nInstanceIndex
)
348 ItemCount nMaxVariations
= 0;
349 rc
= ATSUGetFontInstance( nFontID
, nInstanceIndex
, 0, NULL
, NULL
, &nMaxVariations
);
350 if( (rc
== noErr
) && (nMaxVariations
> 0) )
352 fprintf(stderr
,"\tnMaxVariations=%d\n",(int)nMaxVariations
);
353 typedef ::std::vector
<ATSUFontVariationAxis
> VariationAxisVector
;
354 typedef ::std::vector
<ATSUFontVariationValue
> VariationValueVector
;
355 VariationAxisVector
aVariationAxes( nMaxVariations
);
356 VariationValueVector
aVariationValues( nMaxVariations
);
357 ItemCount nVariationCount
= 0;
358 rc
= ATSUGetFontInstance ( nFontID
, nInstanceIndex
, nMaxVariations
,
359 &aVariationAxes
[0], &aVariationValues
[0], &nVariationCount
);
360 fprintf(stderr
,"\tnVariationCount=%d\n",(int)nVariationCount
);
361 for( ItemCount nVariationIndex
= 0; nVariationIndex
< nMaxVariations
; ++nVariationIndex
)
363 const char* pTag
= (const char*)&aVariationAxes
[nVariationIndex
];
364 fprintf(stderr
,"\tvariation[%d] \'%c%c%c%c\' is %d\n", (int)nVariationIndex
,
365 pTag
[3],pTag
[2],pTag
[1],pTag
[0], (int)aVariationValues
[nVariationIndex
]);
371 #if 0 // selecting non-defaulted font features is not enabled yet
372 ByteString
aFName( rDFA
.maName
, RTL_TEXTENCODING_UTF8
);
373 ByteString
aSName( rDFA
.maStyleName
, RTL_TEXTENCODING_UTF8
);
374 ItemCount nMaxFeatures
= 0;
375 rc
= ATSUCountFontFeatureTypes( nFontID
, &nMaxFeatures
);
376 fprintf(stderr
,"Font \"%s\" \"%s\" has %d features\n",aFName
.GetBuffer(),aSName
.GetBuffer(),rc
);
377 if( (rc
== noErr
) && (nMaxFeatures
> 0) )
379 typedef std::vector
<ATSUFontFeatureType
> FeatureVector
;
380 FeatureVector
aFeatureVector( nMaxFeatures
);
381 ItemCount nFeatureCount
= 0;
382 rc
= ATSUGetFontFeatureTypes( nFontID
, nMaxFeatures
, &aFeatureVector
[0], &nFeatureCount
);
383 fprintf(stderr
,"nFeatureCount=%d\n",(int)nFeatureCount
);
384 for( ItemCount nFeatureIndex
= 0; nFeatureIndex
< nFeatureCount
; ++nFeatureIndex
)
386 ItemCount nMaxSelectors
= 0;
387 rc
= ATSUCountFontFeatureSelectors( nFontID
, aFeatureVector
[nFeatureIndex
], &nMaxSelectors
);
388 fprintf(stderr
,"\tFeature[%d] = %d has %d selectors\n",
389 (int)nFeatureIndex
, (int)aFeatureVector
[nFeatureIndex
], (int)nMaxSelectors
);
390 typedef std::vector
<ATSUFontFeatureSelector
> SelectorVector
;
391 SelectorVector
aSelectorVector( nMaxSelectors
);
392 typedef std::vector
<MacOSBoolean
> BooleanVector
;
393 BooleanVector
aEnabledVector( nMaxSelectors
);
394 BooleanVector
aExclusiveVector( nMaxSelectors
);
395 ItemCount nSelectorCount
= 0;
396 rc
= ATSUGetFontFeatureSelectors ( nFontID
, aFeatureVector
[nFeatureIndex
], nMaxSelectors
,
397 &aSelectorVector
[0], &aEnabledVector
[0], &nSelectorCount
, &aExclusiveVector
[0]);
398 for( ItemCount nSelectorIndex
= 0; nSelectorIndex
< nSelectorCount
; ++nSelectorIndex
)
400 FontNameCode eFontNameCode
;
401 rc
= ATSUGetFontFeatureNameCode( nFontID
, aFeatureVector
[nFeatureIndex
],
402 aSelectorVector
[nSelectorIndex
], &eFontNameCode
);
403 fprintf(stderr
,"\t\tselector[%d] n=%d e=%d, x=%d\n",
404 (int)nSelectorIndex
, (int)eFontNameCode
,
405 aEnabledVector
[nSelectorIndex
], aExclusiveVector
[nSelectorIndex
] );
411 bool bRet
= (rDFA
.maName
.Len() > 0);
415 // =======================================================================
417 SystemFontList::SystemFontList()
419 // count available system fonts
420 ItemCount nATSUICompatibleFontsAvailable
= 0;
421 if( ATSUFontCount(&nATSUICompatibleFontsAvailable
) != noErr
)
423 if( nATSUICompatibleFontsAvailable
<= 0 )
426 // enumerate available system fonts
427 typedef std::vector
<ATSUFontID
> AtsFontIDVector
;
428 AtsFontIDVector
aFontIDVector( nATSUICompatibleFontsAvailable
);
429 ItemCount nFontItemsCount
= 0;
430 if( ATSUGetFontIDs( &aFontIDVector
[0], aFontIDVector
.capacity(), &nFontItemsCount
) != noErr
)
433 BOOST_ASSERT(nATSUICompatibleFontsAvailable
== nFontItemsCount
&& "Strange I would expect them to be equal");
435 // prepare use of the available fonts
436 AtsFontIDVector::const_iterator it
= aFontIDVector
.begin();
437 for(; it
!= aFontIDVector
.end(); ++it
)
439 const ATSUFontID nFontID
= *it
;
440 ImplDevFontAttributes aDevFontAttr
;
441 if( !GetDevFontAttributes( nFontID
, aDevFontAttr
) )
443 ImplMacFontData
* pFontData
= new ImplMacFontData( aDevFontAttr
, nFontID
);
444 maFontContainer
[ nFontID
] = pFontData
;
447 InitGlyphFallbacks();
450 // -----------------------------------------------------------------------
452 SystemFontList::~SystemFontList()
454 MacFontContainer::const_iterator it
= maFontContainer
.begin();
455 for(; it
!= maFontContainer
.end(); ++it
)
457 maFontContainer
.clear();
459 ATSUDisposeFontFallbacks( maFontFallbacks
);
462 // -----------------------------------------------------------------------
464 void SystemFontList::AnnounceFonts( ImplDevFontList
& rFontList
) const
466 MacFontContainer::const_iterator it
= maFontContainer
.begin();
467 for(; it
!= maFontContainer
.end(); ++it
)
468 rFontList
.Add( (*it
).second
->Clone() );
471 // -----------------------------------------------------------------------
473 // not all fonts are suitable for glyph fallback => sort them
474 struct GfbCompare
{ bool operator()(const ImplMacFontData
*, const ImplMacFontData
*); };
476 inline bool GfbCompare::operator()( const ImplMacFontData
* pA
, const ImplMacFontData
* pB
)
478 // use symbol fonts only as last resort
479 bool bPreferA
= !pA
->IsSymbolFont();
480 bool bPreferB
= !pB
->IsSymbolFont();
481 if( bPreferA
!= bPreferB
)
483 // prefer scalable fonts
484 bPreferA
= pA
->IsScalable();
485 bPreferB
= pB
->IsScalable();
486 if( bPreferA
!= bPreferB
)
488 // prefer non-slanted fonts
489 bPreferA
= (pA
->GetSlant() == ITALIC_NONE
);
490 bPreferB
= (pB
->GetSlant() == ITALIC_NONE
);
491 if( bPreferA
!= bPreferB
)
493 // prefer normal weight fonts
494 bPreferA
= (pA
->GetWeight() == WEIGHT_NORMAL
);
495 bPreferB
= (pB
->GetWeight() == WEIGHT_NORMAL
);
496 if( bPreferA
!= bPreferB
)
498 // prefer normal width fonts
499 bPreferA
= (pA
->GetWidthType() == WIDTH_NORMAL
);
500 bPreferB
= (pB
->GetWidthType() == WIDTH_NORMAL
);
501 if( bPreferA
!= bPreferB
)
506 void SystemFontList::InitGlyphFallbacks()
508 // sort fonts for "glyph fallback"
509 typedef std::multiset
<const ImplMacFontData
*,GfbCompare
> FallbackSet
;
510 FallbackSet aFallbackSet
;
511 MacFontContainer::const_iterator it
= maFontContainer
.begin();
512 for(; it
!= maFontContainer
.end(); ++it
)
514 const ImplMacFontData
* pIFD
= (*it
).second
;
515 // TODO: subsettable/embeddable glyph fallback only for PDF export?
516 if( pIFD
->IsSubsettable() || pIFD
->IsEmbeddable() )
517 aFallbackSet
.insert( pIFD
);
520 // tell ATSU about font preferences for "glyph fallback"
521 typedef std::vector
<ATSUFontID
> AtsFontIDVector
;
522 AtsFontIDVector aFallbackVector
;
523 aFallbackVector
.reserve( maFontContainer
.size() );
524 FallbackSet::const_iterator itFData
= aFallbackSet
.begin();
525 for(; itFData
!= aFallbackSet
.end(); ++itFData
)
527 const ImplMacFontData
* pFontData
= (*itFData
);
528 ATSUFontID nFontID
= (ATSUFontID
)pFontData
->GetFontId();
529 aFallbackVector
.push_back( nFontID
);
532 ATSUCreateFontFallbacks( &maFontFallbacks
);
533 ATSUSetObjFontFallbacks( maFontFallbacks
,
534 aFallbackVector
.size(), &aFallbackVector
[0], kATSUSequentialFallbacksPreferred
);
537 // -----------------------------------------------------------------------
539 ImplMacFontData
* SystemFontList::GetFontDataFromId( ATSUFontID nFontId
) const
541 MacFontContainer::const_iterator it
= maFontContainer
.find( nFontId
);
542 if( it
== maFontContainer
.end() )
547 // -----------------------------------------------------------------------