update dev300-m58
[ooovba.git] / vcl / unx / source / gdi / xlfd_attr.cxx
blob64d34f06bf0912c5df039a71269f3464404be852
1 /*************************************************************************
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 *
5 * Copyright 2008 by Sun Microsystems, Inc.
7 * OpenOffice.org - a multi-platform office productivity suite
9 * $RCSfile: xlfd_attr.cxx,v $
10 * $Revision: 1.24 $
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"
33 #include <stdio.h>
34 #include <stdlib.h>
35 #include <string.h>
36 #include <sal/alloca.h>
37 #include "xlfd_attr.hxx"
38 #include <rtl/tencinfo.h>
39 #include <vcl/vclenum.hxx>
41 // ---------------------------------------------------------------------------
44 // Attribute is a container for simple name value pairs
45 // eg. ( "times", FAMILY_ROMAN ) or ( "demi bold", WEIGHT_SEMIBOLD )
46 // enriched with an annotation which is a pretty-printed version of the
47 // string, i.e. "itc avant garde" would get an annotation of "Itc Avant Garde"
50 // ---------------------------------------------------------------------------
52 // release the stored string
53 void
54 Attribute::Release()
56 if ( mpAnnotation != NULL )
57 delete mpAnnotation;
58 if ( mpKeyName != NULL )
59 delete mpKeyName;
60 if ( mpName != NULL )
61 free( (void*)mpName );
64 // get a private copy of the given argument
65 void
66 Attribute::SetName( const char *p, int nLen )
68 mpName = (char*)malloc( nLen + 1 );
69 mnLength = nLen;
70 memcpy( (void*)mpName, p, mnLength );
71 ((char*)mpName)[ mnLength ] = '\0';
74 // Compare whether two strings a equal for the first nLen bytes
75 // i.e. arial == arialnarrow
76 int
77 Attribute::Compare( const char *p, int nLen )
79 return strncmp( mpName, p, nLen );
82 // Get a all lowercase name with all blanks removed
83 const rtl::OString&
84 Attribute::GetKey ()
86 static rtl::OString aEmptyStr;
88 if (mpKeyName != NULL)
89 return *mpKeyName;
90 if (mnLength == 0)
91 return aEmptyStr;
93 sal_Char* pBuffer = (sal_Char*)alloca (mnLength);
95 sal_Int32 i, j;
96 for (i = 0, j = 0; i < mnLength; i++)
98 if ( mpName[i] != ' ' )
99 pBuffer[j++] = mpName[i];
101 mpKeyName = new rtl::OString(pBuffer, j);
103 return *mpKeyName;
106 void
107 Attribute::InitKey ()
109 mpKeyName = NULL;
112 // Compare two strings, they have to be equal for nLen bytes, after nLen
113 // bytes both strings have to be terminated either by '\0' or by '-'
114 // this is for comparing a string being a substring in a Xlfd with a
115 // zeroterminated string
116 Bool
117 Attribute::ExactMatch( const char *p, int nLen )
119 Bool bMatch;
120 if ( nLen > 0 )
121 bMatch = Compare( p, nLen ) == 0;
122 else
123 bMatch = True;
124 if ( bMatch )
126 char c1 = p[ nLen ];
127 char c2 = mpName[ nLen ];
128 bMatch = (c1 == '-' || c1 == '\0') && (c2 == '-' || c2 == '\0');
131 return bMatch;
134 void
135 Attribute::TagFeature( unsigned short nFeature )
137 if ( (nFeature & XLFD_FEATURE_NARROW)
138 && (strstr(mpName, "narrow") != NULL) )
140 mnFeature |= XLFD_FEATURE_NARROW;
143 if ( (nFeature & XLFD_FEATURE_OL_CURSOR)
144 && (strcmp(mpName, "open look cursor") == 0) )
146 mnFeature |= XLFD_FEATURE_OL_CURSOR;
149 if ( (nFeature & XLFD_FEATURE_OL_GLYPH)
150 && (strcmp(mpName, "open look glyph") == 0) )
152 mnFeature |= XLFD_FEATURE_OL_GLYPH;
155 if ( (nFeature & XLFD_FEATURE_APPLICATION_FONT)
156 && ( (strcmp(mpName, "interface user") == 0)
157 || (strcmp(mpName, "interface system") == 0)))
159 mnFeature |= XLFD_FEATURE_APPLICATION_FONT;
162 if (nFeature & XLFD_FEATURE_INTERFACE_FONT)
164 // european
165 if (strcmp(mpName, "arial") == 0)
166 mnFeature |= (XLFD_FEATURE_INTERFACE_FONT | XLFD_FEATURE_HQ | XLFD_FEATURE_MQ);
167 else
168 if (strcmp(mpName, "helvetica") == 0)
169 mnFeature |= (XLFD_FEATURE_INTERFACE_FONT | XLFD_FEATURE_HQ);
170 else
171 if ( (strcmp(mpName, "lucidux sans") == 0)
172 || (strcmp(mpName, "luxi sans") == 0))
173 mnFeature |= (XLFD_FEATURE_INTERFACE_FONT | XLFD_FEATURE_MQ | XLFD_FEATURE_LQ);
174 else
175 if (strcmp(mpName, "charter") == 0)
176 mnFeature |= (XLFD_FEATURE_INTERFACE_FONT | XLFD_FEATURE_MQ);
177 else
178 // japanese
179 if ( (strcmp(mpName, "hg mincho l") == 0) /* Solaris: jisx0208 jisx0201 */
180 || (strcmp(mpName, "heiseimin") == 0) /* Solaris: jisx0212 */
181 || (strcmp(mpName, "minchol") == 0) /* TurboLinux */
182 || (strcmp(mpName, "mincho") == 0)) /* Redhat 6.2 JP */
184 mnFeature |= XLFD_FEATURE_INTERFACE_FONT;
186 else
187 // chinese
188 if ( (strcmp(mpName, "kai") == 0) /* Solaris */
189 || (strcmp(mpName, "ar pl mingti2l big5") == 0)) /* TurboLinux */
191 mnFeature |= XLFD_FEATURE_INTERFACE_FONT;
193 else
194 // korean
195 if ( (strcmp(mpName, "myeongjo") == 0)) /* Solaris */
197 mnFeature |= XLFD_FEATURE_INTERFACE_FONT;
201 if ( nFeature & XLFD_FEATURE_REDUNDANTSTYLE )
203 switch ( mpName[0] )
205 case '\0':
206 mnFeature |= XLFD_FEATURE_REDUNDANTSTYLE;
207 break;
209 case 'b':
210 if ( (strcmp(mpName, "bold") == 0)
211 || (strcmp(mpName, "bold italic") == 0)
212 || (strcmp(mpName, "bold sans") == 0) )
213 mnFeature |= XLFD_FEATURE_REDUNDANTSTYLE;
214 break;
216 case 'd':
217 if ( (strcmp(mpName, "demi") == 0)
218 || (strcmp(mpName, "demi italic") == 0) )
219 mnFeature |= XLFD_FEATURE_REDUNDANTSTYLE;
220 break;
222 case 'i':
223 if ( strcmp(mpName, "italic") == 0 )
224 mnFeature |= XLFD_FEATURE_REDUNDANTSTYLE;
225 break;
227 case 's':
228 if ( (strcmp(mpName, "sans") == 0)
229 || (strcmp(mpName, "serif") == 0) )
230 mnFeature |= XLFD_FEATURE_REDUNDANTSTYLE;
231 break;
236 // given Attribute classifications, strings have to be in alphabetical
237 // order, since they are treated by binary search algorithm
239 #define InitializeAttributeWith( p, a ) p, sizeof(p) - 1, a, 0, NULL, NULL
240 #define MembersOf( p ) (sizeof(p) / sizeof(p[0]) )
242 const Attribute pFamilyAttribute[] = {
243 { InitializeAttributeWith( "arial", FAMILY_SWISS ) },
244 { InitializeAttributeWith( "arioso", FAMILY_SCRIPT ) },
245 { InitializeAttributeWith( "avant garde", FAMILY_SWISS ) },
246 { InitializeAttributeWith( "avantgarde", FAMILY_SWISS ) },
247 { InitializeAttributeWith( "bembo", FAMILY_ROMAN ) },
248 { InitializeAttributeWith( "bookman", FAMILY_ROMAN ) },
249 { InitializeAttributeWith( "conga", FAMILY_ROMAN ) },
250 { InitializeAttributeWith( "courier", FAMILY_MODERN ) },
251 { InitializeAttributeWith( "curl", FAMILY_SCRIPT ) },
252 { InitializeAttributeWith( "fixed", FAMILY_MODERN ) },
253 { InitializeAttributeWith( "gill", FAMILY_SWISS ) },
254 { InitializeAttributeWith( "helmet", FAMILY_MODERN ) },
255 { InitializeAttributeWith( "helvetica", FAMILY_SWISS ) },
256 { InitializeAttributeWith( "international", FAMILY_MODERN ) },
257 { InitializeAttributeWith( "lucida", FAMILY_SWISS ) },
258 { InitializeAttributeWith( "new century schoolbook", FAMILY_ROMAN ) },
259 { InitializeAttributeWith( "palatino", FAMILY_ROMAN ) },
260 { InitializeAttributeWith( "roman", FAMILY_ROMAN ) },
261 { InitializeAttributeWith( "sans serif", FAMILY_SWISS ) },
262 { InitializeAttributeWith( "sansserif", FAMILY_SWISS ) },
263 { InitializeAttributeWith( "serf", FAMILY_ROMAN ) },
264 { InitializeAttributeWith( "serif", FAMILY_ROMAN ) },
265 { InitializeAttributeWith( "times", FAMILY_ROMAN ) },
266 { InitializeAttributeWith( "utopia", FAMILY_ROMAN ) },
267 { InitializeAttributeWith( "zapf chancery", FAMILY_SCRIPT ) },
268 { InitializeAttributeWith( "zapfchancery", FAMILY_SCRIPT ) }
271 const Attribute pWeightAttribute[] = {
272 { InitializeAttributeWith( "black", WEIGHT_BLACK ) },
273 { InitializeAttributeWith( "bold", WEIGHT_BOLD ) },
274 { InitializeAttributeWith( "book", WEIGHT_LIGHT ) },
275 { InitializeAttributeWith( "demi", WEIGHT_SEMIBOLD ) },
276 { InitializeAttributeWith( "demi bold", WEIGHT_SEMIBOLD ) },
277 { InitializeAttributeWith( "demibold", WEIGHT_SEMIBOLD ) },
278 { InitializeAttributeWith( "light", WEIGHT_LIGHT ) },
279 { InitializeAttributeWith( "medium", WEIGHT_MEDIUM ) },
280 { InitializeAttributeWith( "normal", WEIGHT_NORMAL ) },
281 { InitializeAttributeWith( "regular", WEIGHT_NORMAL ) },
282 { InitializeAttributeWith( "roman", WEIGHT_NORMAL ) },
283 { InitializeAttributeWith( "semicondensed", WEIGHT_LIGHT ) },
284 { InitializeAttributeWith( "ultrabold", WEIGHT_ULTRABOLD ) }
287 const Attribute pSlantAttribute[] = {
288 { InitializeAttributeWith( "i", ITALIC_NORMAL ) },
289 { InitializeAttributeWith( "o", ITALIC_OBLIQUE ) },
290 { InitializeAttributeWith( "r", ITALIC_NONE ) }
293 const Attribute pSetwidthAttribute[] = {
294 { InitializeAttributeWith( "bold", WIDTH_SEMI_EXPANDED ) },
295 { InitializeAttributeWith( "condensed", WIDTH_CONDENSED ) },
296 { InitializeAttributeWith( "double wide", WIDTH_ULTRA_EXPANDED ) },
297 { InitializeAttributeWith( "expanded", WIDTH_EXPANDED ) },
298 { InitializeAttributeWith( "extracondensed", WIDTH_EXTRA_CONDENSED ) },
299 { InitializeAttributeWith( "extraexpanded", WIDTH_EXTRA_EXPANDED ) },
300 { InitializeAttributeWith( "medium", WIDTH_NORMAL ) },
301 { InitializeAttributeWith( "narrow", WIDTH_CONDENSED ) },
302 { InitializeAttributeWith( "normal", WIDTH_NORMAL ) },
303 { InitializeAttributeWith( "semicondensed", WIDTH_SEMI_CONDENSED ) },
304 { InitializeAttributeWith( "semiexpanded", WIDTH_SEMI_EXPANDED ) },
305 { InitializeAttributeWith( "ultracondensed", WIDTH_ULTRA_CONDENSED ) },
306 { InitializeAttributeWith( "ultraexpanded", WIDTH_ULTRA_EXPANDED ) },
307 { InitializeAttributeWith( "wide", WIDTH_EXPANDED ) }
310 const Attribute pEnhancedCharsetAttribute[] = {
311 { InitializeAttributeWith( "iso8859-1", RTL_TEXTENCODING_MS_1252 ) },
312 { InitializeAttributeWith( "iso8859_1", RTL_TEXTENCODING_MS_1252 ) }
315 // -------------------------------------------------------------------------
317 // String handling utility functions
319 // -------------------------------------------------------------------------
322 void
323 AppendAttribute( Attribute *pAttribute, ByteString &rString )
325 if ( pAttribute == NULL )
326 return ;
328 int nLength = pAttribute->GetLength();
329 char *pBuffer = (char*)alloca( nLength + 1);
331 pBuffer[ 0 ] = '-';
332 memcpy( pBuffer + 1, pAttribute->GetName(), nLength );
333 rString.Append( pBuffer, nLength + 1);
337 // Prettify the font name: make each leading character of a fontname
338 // uppercase. For example
339 // times new roman -> Times New Roman
342 static void
343 ToUpper( char *pCharacter )
345 // replace [a,z] with [A,Z]
346 if ( (*pCharacter >= 97) && (*pCharacter <= 122) )
347 *pCharacter -= 32;
350 static String*
351 Capitalize( const char *pStr, int nLength )
353 char *pCopy = (char*)alloca( nLength + 1 );
354 char *pPtr = pCopy;
355 memcpy( pPtr, pStr, nLength + 1 );
357 // loop over string data and uppercase first char and all chars
358 // following a space (other white space would be unexpected here)
359 char nPreviousChar = ' ';
360 while ( *pPtr )
362 if ( nPreviousChar == ' ' )
363 ToUpper( pPtr );
364 nPreviousChar = *pPtr++;
367 return new String( pCopy, RTL_TEXTENCODING_ISO_8859_1 );
370 String*
371 AnnotateString( const Attribute& rAttribute )
373 return Capitalize(rAttribute.GetName(), rAttribute.GetLength());
376 String*
377 AnnotateSlant( const Attribute& rAttribute )
379 const char* pStr = rAttribute.GetName();
380 int nLen = rAttribute.GetLength();
382 static const struct {
383 const char *pFrom; const char *pTo;
384 } pTranslation[] = {
385 { "r", "Roman" },
386 { "o", "Oblique" },
387 { "i", "Italic" },
388 { "ri", "Reverse Italic" },
389 { "ro", "Reverse Oblique" },
390 { "ot", "Other" }
393 for ( unsigned int i = 0; i < MembersOf(pTranslation); i++ )
394 if ( strcmp(pStr, pTranslation[i].pFrom) == 0 )
396 return new String( pTranslation[i].pTo,
397 RTL_TEXTENCODING_ISO_8859_1 );
400 return Capitalize(pStr, nLen);
403 String*
404 AnnotateNone( const Attribute& )
406 return new String();
409 // ---------------------------------------------------------------------------
412 // manage global lists of Attributes
413 // since XListFonts does never list more than 64K fonts this storage does
414 // handle array size and indices with unsigned short values for low
415 // memory consumption
418 // ---------------------------------------------------------------------------
420 AttributeStorage::AttributeStorage( unsigned short nDefaultValue ) :
421 mpList( NULL ),
422 mnSize( 0 ),
423 mnCount( 0 ),
424 mnLastmatch( 0 ),
425 mnDefaultValue( nDefaultValue )
429 AttributeStorage::~AttributeStorage()
431 if ( mpList != NULL )
433 for ( int i = 0; i < mnCount; i++ )
434 mpList[i].Release();
435 free( mpList );
439 #if OSL_DEBUG_LEVEL > 1
440 void
441 AttributeStorage::Dump()
443 fprintf(stderr, "AttributeStorage: size=%i, used=%i\n", mnSize, mnCount);
444 for ( int i = 0; i < mnCount; i++ )
446 ByteString aAnnotation = ByteString(
447 mpList[i].GetAnnotation(),
448 RTL_TEXTENCODING_ISO_8859_1 );
449 fprintf(stderr, "\t%4i: <%s><len=%i><val=%i><%s>\n", i, mpList[i].GetName(),
450 mpList[i].GetLength(), mpList[i].GetValue(),
451 aAnnotation.GetBuffer() );
453 fprintf(stderr, "\n");
455 #endif
457 Attribute*
458 AttributeStorage::Retrieve( unsigned short nIndex ) const
460 return nIndex < mnCount ? &mpList[ nIndex ] : (Attribute*)NULL ;
463 // pClassification contains a list of name-value pairs. If names in
464 // the AttributeStorage match those in the pClassification then
465 // the according value is copied. Matching means match for the length
466 // of the string in pClassification (i.e. arial matches arialnarrow)
467 // the strings in pClassification must be in alphabetical order, all
468 // strings Lowercase
469 void
470 AttributeStorage::AddClassification( Attribute *pClassification,
471 unsigned short nNum )
473 for ( int i = 0; i < mnCount; i++ )
475 unsigned int nLower = 0;
476 unsigned int nUpper = nNum;
477 unsigned int nCurrent;
478 int nComparison = 1;
479 Attribute *pHaystack = 0, *pNeedle;
481 pNeedle = &mpList[ i ];
483 // binary search
484 while ( nLower < nUpper )
486 nCurrent = (nLower + nUpper) / 2;
487 pHaystack = &pClassification[ nCurrent ];
488 nComparison = pNeedle->Compare( pHaystack->GetName(),
489 pHaystack->GetLength() );
490 if (nComparison < 0)
491 nUpper = nCurrent;
492 else
493 if (nComparison > 0)
494 nLower = nCurrent + 1;
495 else
496 break;
499 // if there's a match store the according classification in the
500 // Attribute storage, otherwise do nothing since defaults are
501 // already provided in AttributeStorage::Insert()
502 if ( nComparison == 0 )
503 pNeedle->SetValue( pHaystack->GetValue() );
507 void
508 AttributeStorage::AddClassification( AttributeClassifierT Classify )
510 for ( int i = 0; i < mnCount; i++ )
512 Attribute& rCurrent = mpList[i] ;
513 int nValue = Classify( rCurrent.GetName() );
514 rCurrent.SetValue( nValue );
518 void
519 AttributeStorage::AddAnnotation( AttributeAnnotatorT Annotate )
521 for ( int i = 0; i < mnCount; i++ )
523 String* pAnnotation = Annotate( mpList[i] );
524 mpList[i].SetAnnotation( pAnnotation );
528 void
529 AttributeStorage::TagFeature( unsigned short nFeature )
531 for ( int i = 0; i < mnCount; i++ )
532 mpList[i].TagFeature( nFeature );
535 // Enlarge the list of Attributes
536 void
537 AttributeStorage::Enlarge()
539 if ( mnSize == 0 )
541 mnSize = 8;
542 mpList = (Attribute*) malloc( mnSize * sizeof(Attribute) );
544 else
546 mnSize = mnSize < 32768 ? (mnSize * 2) : 65535;
547 mpList = (Attribute*) realloc( mpList, mnSize * sizeof(Attribute) );
551 // nLength is the length as it would be reported by strlen(3)
552 // for an null-terminated string. if a string is part of a Xlfd
553 // the field separator '-' is taken as '\0'
554 // the AttributeStorage itself is NOT sorted to make sure that the
555 // leased keys are still valid
556 unsigned short
557 AttributeStorage::Insert( const char *pString, int nLength )
559 // check whether the last match is still equal to the current
560 // string since XListFonts lists fonts in sets of similar fontnames
561 if ( mnLastmatch < mnCount )
563 if ( mpList[mnLastmatch].ExactMatch(pString, nLength) )
564 return mnLastmatch;
567 // otherwise search in list
568 for ( int i = 0; i < mnCount; i++ )
570 if ( mpList[i].ExactMatch(pString, nLength) )
571 return mnLastmatch = i;
574 // if still not found we have to Insert the new string
575 if ( mnSize == mnCount )
576 Enlarge();
577 mpList[mnCount].SetName( pString, nLength );
578 mpList[mnCount].SetValue( mnDefaultValue );
579 mpList[mnCount].SetAnnotation( NULL );
580 mpList[mnCount].SetFeature( XLFD_FEATURE_NONE );
581 mpList[mnCount].InitKey( );
582 mnLastmatch = mnCount;
583 mnCount = mnCount < 65535 ? mnCount + 1 : mnCount;
585 return mnLastmatch;
589 // ---------------------------------------------------------------------------
592 // Attribute provider is a frame for a set of AttributeStorages.
595 // ---------------------------------------------------------------------------
597 AttributeProvider::AttributeProvider ()
599 mpField[eXLFDFoundry ] = new AttributeStorage(0);
600 mpField[eXLFDFamilyName ] = new AttributeStorage(FAMILY_DONTKNOW);
601 mpField[eXLFDWeightName ] = new AttributeStorage(WEIGHT_NORMAL);
602 mpField[eXLFDSlant ] = new AttributeStorage(ITALIC_NONE);
603 mpField[eXLFDSetwidthName] = new AttributeStorage(WIDTH_NORMAL);
604 mpField[eXLFDAddstyleName] = new AttributeStorage(RTL_TEXTENCODING_DONTKNOW);
605 mpField[eXLFDCharset ] = new AttributeStorage(RTL_TEXTENCODING_DONTKNOW);
608 AttributeProvider::~AttributeProvider()
610 for ( int i = 0; i < eXLFDMaxEntry; i++ )
611 delete mpField[ i ];
614 #if OSL_DEBUG_LEVEL > 1
615 void
616 AttributeProvider::Dump()
618 for ( int i = 0; i < eXLFDMaxEntry; i++ )
619 mpField[ i ]->Dump();
621 #endif
623 extern "C" rtl_TextEncoding
624 GetTextEncodingFromAddStylename( const sal_Char *pAddStylename )
626 int nBufferLength = strlen( pAddStylename ) + 1;
627 sal_Char *pBuffer = (sal_Char*)alloca( nBufferLength );
628 for ( int i = 0; i < nBufferLength; i++ )
629 pBuffer[i] = pAddStylename[i] == '_' ? '-' : pAddStylename[i] ;
631 return rtl_getTextEncodingFromUnixCharset( pBuffer );
635 // classification information is needed before sorting because of course the
636 // classification is the sort criteria
637 void
638 AttributeProvider::AddClassification()
640 /* mpField[ eXLFDFoundry ] doesn't need classification */
641 mpField[ eXLFDFamilyName ]->AddClassification(
642 (Attribute*)pFamilyAttribute,
643 MembersOf(pFamilyAttribute) );
644 mpField[ eXLFDWeightName ]->AddClassification(
645 (Attribute*)pWeightAttribute,
646 MembersOf(pWeightAttribute) );
647 mpField[ eXLFDSlant ]->AddClassification(
648 (Attribute*)pSlantAttribute,
649 MembersOf(pSlantAttribute) );
650 mpField[ eXLFDSetwidthName ]->AddClassification(
651 (Attribute*)pSetwidthAttribute,
652 MembersOf(pSetwidthAttribute) );
653 mpField[ eXLFDAddstyleName ]->AddClassification(
654 GetTextEncodingFromAddStylename );
655 mpField[ eXLFDCharset ]->AddClassification(
656 rtl_getTextEncodingFromUnixCharset );
659 // add some pretty print description
660 void
661 AttributeProvider::AddAnnotation()
663 mpField[ eXLFDFoundry ]->AddAnnotation( AnnotateNone );
664 mpField[ eXLFDFamilyName ]->AddAnnotation( AnnotateString );
665 mpField[ eXLFDWeightName ]->AddAnnotation( AnnotateString );
666 mpField[ eXLFDSlant ]->AddAnnotation( AnnotateSlant );
667 mpField[ eXLFDSetwidthName ]->AddAnnotation( AnnotateString );
668 mpField[ eXLFDAddstyleName ]->AddAnnotation( AnnotateNone );
669 mpField[ eXLFDCharset ]->AddAnnotation( AnnotateNone );
672 // this is the misc or any section: dirty hacks for dirty xlfd usage
673 void
674 AttributeProvider::TagFeature()
676 mpField[ eXLFDFamilyName ]->TagFeature(
677 XLFD_FEATURE_OL_GLYPH
678 | XLFD_FEATURE_OL_CURSOR
679 | XLFD_FEATURE_NARROW
680 | XLFD_FEATURE_INTERFACE_FONT
681 | XLFD_FEATURE_APPLICATION_FONT);
683 mpField[ eXLFDSetwidthName ]->TagFeature(
684 XLFD_FEATURE_NARROW );
686 mpField[ eXLFDAddstyleName ]->TagFeature(
687 XLFD_FEATURE_REDUNDANTSTYLE );