[Top][All Lists]
[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 )
- [Devel] Passing style,
John A. Boyd Jr. <=