freetype-devel
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Devel] Passing style


From: John A. Boyd Jr.
Subject: [Devel] Passing style
Date: Wed, 12 Nov 2003 10:58:04 -0500
User-agent: Mozilla/5.0 (X11; U; Linux i686; en-US; rv:1.4) Gecko/20030624 Netscape/7.1

Hello,

I don't want to get heavily involved in Freetype code, but I've just
fixed a problem for myself that's been bugging me for a while, and I
want to pass along my patch.  If it's of interest to someone on this
list, my purpose will have been achieved... If the patch is not of
interest, that's OK with me.

As of 2.1.5, freetype doesn't preserve the "set width" or "add style"
attributes of BDF/PCF fonts.  That's been a problem for me because some
of the fonts I like to use have both "normal" and "semicondensed"
variants for the same size (I'm talking about the stock X "misc-fixed"
fonts).  fontconfig via freetype hasn't been able to tell the normal
from the semicondensed, so the semicondensed can't be "seen" by apps
they support, prior to this patch.

I spent some time in the last few days finally looking for a clean
solution to this problem, and it seems to me that it is appropriate in
general for freetype to pass non-normal "set width" as a component of
the freetype "style".  Pango, for instance, already expects "stretch"
(which includes "semicondensed") as a style component, but it must get
there first, and it doesn't unless freetype makes it somehow available.

The patch I'm attaching changes the PCF/BDF code to deal differently
with setting the freetype "style".  Prior to this (as of 2.1.5), only
"bold" and "italic" were checked for and accomodated.  This patch
replaces that code with a routine which builds a "style" which may
include not only "bold" and "italic", but also whatever non-normal
contents "set width" and "add style" may have.

I've actually commented out the use of "add style" in the patch,
subject to a macro definition.  With the "set width" choice similarly
commented out, behavior will be identical to the older code.  I have
"add style" commented out because, among the stock X fonts, only
"sans" is ever used in that attribute, and passing it along is not
necessary.

I've only joined this list to be able to pass along this patch.  I'm
really not interested in getting up to date with freetype development,
using your CVS interface, etc.  I'm hoping instead that someone on
this list can find it of interest, and use it if it seems useful.

-John
--- freetype-2.1.5/include/freetype/config/ftstdlib.h.addstyle  2003-05-21 
03:39:40.000000000 -0400
+++ freetype-2.1.5/include/freetype/config/ftstdlib.h   2003-11-12 
10:00:11.000000000 -0500
@@ -77,7 +77,8 @@
 #define ft_isupper  isupper
 #define ft_islower  islower
 #define ft_xdigit   isxdigit
-
+#define ft_toupper  toupper
+#define ft_tolower  tolower
 
 #include <string.h>
 
--- freetype-2.1.5/src/bdf/bdfdrivr.c.addstyle  2003-09-01 03:06:06.000000000 
-0400
+++ freetype-2.1.5/src/bdf/bdfdrivr.c   2003-11-12 10:02:01.000000000 -0500
@@ -169,6 +169,88 @@
   };
 
 
+  static FT_Error
+  _bdf_interpret_style( BDF_Face bdf )
+  {
+      FT_Face           ft = FT_FACE( bdf );
+      FT_Error       error = BDF_Err_Ok;
+      FT_Memory     memory = FT_FACE(bdf)->memory;
+      bdf_font_t     *font = bdf->bdffont;
+      bdf_property_t *prop;
+      char *istr = NULL, *bstr = NULL;
+      char *sstr = NULL, *astr = NULL;
+      int parts = 0, len = 0;  
+
+      ft->style_flags = 0;
+
+      prop = bdf_get_font_property( font, (char *)"SLANT" );
+      if (prop && prop->format == BDF_ATOM && prop->value.atom &&
+         (ft_toupper(*(prop->value.atom)) == 'O' ||
+          ft_toupper(*(prop->value.atom)) == 'I'))
+      {
+         ft->style_flags |= FT_STYLE_FLAG_ITALIC;
+         istr = (ft_toupper(*(prop->value.atom)) == 'O' ? "Oblique" : 
"Italic");
+         len += ft_strlen(istr);  parts++;
+      }
+
+      prop = bdf_get_font_property( font, (char *)"WEIGHT_NAME" );
+      if (prop && prop->format == BDF_ATOM && prop->value.atom &&
+         ft_toupper(*(prop->value.atom)) == 'B')
+      {
+         ft->style_flags |= FT_STYLE_FLAG_BOLD;
+         bstr = "Bold";
+         len += ft_strlen(bstr);  parts++;
+      }
+
+      prop = bdf_get_font_property( font, (char *)"SETWIDTH_NAME" );
+      if (prop && prop->format == BDF_ATOM && prop->value.atom &&
+         *(prop->value.atom) && ft_toupper(*(prop->value.atom)) != 'N')
+      {
+         sstr = (char *)(prop->value.atom);
+         len += ft_strlen(sstr);  parts++;
+      }
+
+#ifdef USE_ADD_STYLE
+      prop = bdf_get_font_property( font, (char *)"ADD_STYLE_NAME" );
+      if (prop && prop->format == BDF_ATOM && prop->value.atom &&
+         *(prop->value.atom) && ft_toupper(*(prop->value.atom)) != 'N')
+      {
+         astr = (char *)(prop->value.atom);
+         len += ft_strlen(astr);  parts++;
+      }
+#endif
+
+      if (!parts || !len)
+         ft->style_name = (char *)"Regular";
+      else {
+         char *style, *s; 
+
+         if (FT_ALLOC(style,(len+parts)))
+             return error;
+
+         s = style;
+
+         if (astr) {
+             ft_strcpy(s, astr);  s += ft_strlen(astr);  *(s++) = ' ';
+         }
+         if (bstr) {
+             ft_strcpy(s, bstr);  s += ft_strlen(bstr);  *(s++) = ' ';
+         }
+         if (istr) {
+             ft_strcpy(s, istr);  s += ft_strlen(istr);  *(s++) = ' ';
+         }
+         if (sstr) {
+             ft_strcpy(s, sstr);  s += ft_strlen(sstr);  *(s++) = ' ';
+         }
+         *(--s) = 0;  /* overwrite last ' ', terminate the string */
+
+         ft->style_name = style;  /* allocated string */
+      }
+
+      return error;
+  }
+
+
   FT_CALLBACK_DEF( FT_Error )
   BDF_Face_Done( BDF_Face  face )
   {
@@ -252,34 +334,13 @@
       if ( prop != NULL )
         if ( prop->format == BDF_ATOM )
           if ( prop->value.atom != NULL )
-            if ( ( *(prop->value.atom) == 'M' ) ||
-                 ( *(prop->value.atom) == 'm' ) ||
-                 ( *(prop->value.atom) == 'C' ) ||
-                 ( *(prop->value.atom) == 'c' ) )
+            if ( ( ft_toupper(*(prop->value.atom)) == 'M' ) ||
+                ( ft_toupper(*(prop->value.atom)) == 'C' ) )
               root->face_flags |= FT_FACE_FLAG_FIXED_WIDTH;
 
       /* FZ XXX: TO DO: FT_FACE_FLAGS_VERTICAL   */
       /* FZ XXX: I need a font to implement this */
 
-      root->style_flags = 0;
-      prop = bdf_get_font_property( font, "SLANT" );
-      if ( prop != NULL )
-        if ( prop->format == BDF_ATOM )
-          if ( prop->value.atom != NULL )
-            if ( ( *(prop->value.atom) == 'O' ) ||
-                 ( *(prop->value.atom) == 'o' ) ||
-                 ( *(prop->value.atom) == 'I' ) ||
-                 ( *(prop->value.atom) == 'i' ) )
-              root->style_flags |= FT_STYLE_FLAG_ITALIC;
-
-      prop = bdf_get_font_property( font, "WEIGHT_NAME" );
-      if ( prop != NULL )
-        if ( prop->format == BDF_ATOM )
-          if ( prop->value.atom != NULL )
-            if ( ( *(prop->value.atom) == 'B' ) ||
-                 ( *(prop->value.atom) == 'b' ) )
-              root->style_flags |= FT_STYLE_FLAG_BOLD;
-
       prop = bdf_get_font_property( font, "FAMILY_NAME" );
       if ( ( prop != NULL ) && ( prop->value.atom != NULL ) )
       {
@@ -293,16 +354,8 @@
       else
         root->family_name = 0;
 
-      root->style_name = (char *)"Regular";
-      if ( root->style_flags & FT_STYLE_FLAG_BOLD )
-      {
-        if ( root->style_flags & FT_STYLE_FLAG_ITALIC )
-          root->style_name = (char *)"Bold Italic";
-        else
-          root->style_name = (char *)"Bold";
-      }
-      else if ( root->style_flags & FT_STYLE_FLAG_ITALIC )
-        root->style_name = (char *)"Italic";
+      if ((error = _bdf_interpret_style(face)))
+         goto Exit;
 
       root->num_glyphs = font->glyphs_size;     /* unencoded included */
 
--- freetype-2.1.5/src/pcf/pcfread.c.addstyle   2003-08-28 06:57:05.000000000 
-0400
+++ freetype-2.1.5/src/pcf/pcfread.c    2003-11-12 10:02:24.000000000 -0500
@@ -862,6 +862,86 @@
   }
 
 
+  static FT_Error
+  pcf_interpret_style( PCF_Face pcf )
+  {
+      FT_Face         ft = FT_FACE( pcf );
+      FT_Error     error = PCF_Err_Ok;
+      FT_Memory   memory = FT_FACE(pcf)->memory;
+      PCF_Property  prop;
+      char *istr = NULL, *bstr = NULL;
+      char *sstr = NULL, *astr = NULL;
+      int parts = 0, len = 0;  
+
+      ft->style_flags = 0;
+
+      prop = pcf_find_property( pcf, "SLANT" );
+      if (prop && prop->isString &&
+         (ft_toupper(*(prop->value.atom)) == 'O' ||
+          ft_toupper(*(prop->value.atom)) == 'I'))
+      {
+         ft->style_flags |= FT_STYLE_FLAG_ITALIC;
+         istr = (ft_toupper(*(prop->value.atom)) == 'O' ? "Oblique" : 
"Italic");
+         len += ft_strlen(istr);  parts++;
+      }
+
+      prop = pcf_find_property( pcf, "WEIGHT_NAME" );
+      if (prop && prop->isString && *(prop->value.atom) == 'B')
+      {
+         ft->style_flags |= FT_STYLE_FLAG_BOLD;
+         bstr = "Bold";
+         len += ft_strlen(bstr);  parts++;
+      }
+
+      prop = pcf_find_property( pcf, "SETWIDTH_NAME" );
+      if (prop && prop->isString && *(prop->value.atom) &&
+         ft_toupper(*(prop->value.atom)) != 'N')
+      {
+         sstr = (char *)(prop->value.atom);
+         len += ft_strlen(sstr);  parts++;
+      }
+
+#ifdef USE_ADD_STYLE
+      prop = pcf_find_property( pcf, "ADD_STYLE_NAME" );
+      if (prop && prop->isString && *(prop->value.atom) &&
+         ft_toupper(*(prop->value.atom)) != 'N')
+      {
+         astr = (char *)(prop->value.atom);
+         len += ft_strlen(astr);  parts++;
+      }
+#endif
+
+      if (!parts || !len)
+         ft->style_name = (char *)"Regular";
+      else {
+         char *style, *s; 
+
+         if (FT_ALLOC(style,(len+parts)))
+             return error;
+
+         s = style;
+
+         if (astr) {
+             ft_strcpy(s, astr);  s += ft_strlen(astr);  *(s++) = ' ';
+         }
+         if (bstr) {
+             ft_strcpy(s, bstr);  s += ft_strlen(bstr);  *(s++) = ' ';
+         }
+         if (istr) {
+             ft_strcpy(s, istr);  s += ft_strlen(istr);  *(s++) = ' ';
+         }
+         if (sstr) {
+             ft_strcpy(s, sstr);  s += ft_strlen(sstr);  *(s++) = ' ';
+         }
+         *(--s) = 0;  /* overwrite last ' ', terminate the string */
+
+         ft->style_name = style;  /* allocated string */
+      }
+
+      return error;
+  }
+
+
   FT_LOCAL_DEF( FT_Error )
   pcf_load_font( FT_Stream  stream,
                  PCF_Face   face )
@@ -930,33 +1010,8 @@
       if ( face->accel.constantWidth )
         root->face_flags |= FT_FACE_FLAG_FIXED_WIDTH;
 
-      root->style_flags = 0;
-      prop = pcf_find_property( face, "SLANT" );
-      if ( prop != NULL )
-        if ( prop->isString )
-          if ( ( *(prop->value.atom) == 'O' ) ||
-               ( *(prop->value.atom) == 'o' ) ||
-               ( *(prop->value.atom) == 'I' ) ||
-               ( *(prop->value.atom) == 'i' ) )
-            root->style_flags |= FT_STYLE_FLAG_ITALIC;
-
-      prop = pcf_find_property( face, "WEIGHT_NAME" );
-      if ( prop != NULL )
-        if ( prop->isString )
-          if ( ( *(prop->value.atom) == 'B' ) ||
-               ( *(prop->value.atom) == 'b' ) )
-            root->style_flags |= FT_STYLE_FLAG_BOLD;
-
-      root->style_name = (char *)"Regular";
-
-      if ( root->style_flags & FT_STYLE_FLAG_BOLD ) {
-        if ( root->style_flags & FT_STYLE_FLAG_ITALIC )
-          root->style_name = (char *)"Bold Italic";
-        else
-          root->style_name = (char *)"Bold";
-      }
-      else if ( root->style_flags & FT_STYLE_FLAG_ITALIC )
-        root->style_name = (char *)"Italic";
+      if ((error = pcf_interpret_style( face )))
+         goto Exit;
 
       prop = pcf_find_property( face, "FAMILY_NAME" );
       if ( prop != NULL )

reply via email to

[Prev in Thread] Current Thread [Next in Thread]