static FT_Error pcf_get_bdf_property( PCF_Face face, const char* prop_name, BDF_PropertyRec *aproperty ) { PCF_Property prop; prop = pcf_find_property( face, prop_name ); if ( prop != NULL ) { if ( prop->isString ) { aproperty->type = BDF_PROPERTY_TYPE_ATOM; aproperty->u.atom = prop->value.atom; } else { /* Apparently, the PCF driver loads all properties as signed integers! * This really doesn't seem to be a problem, because this is * sufficient for any meaningful values. */ aproperty->type = BDF_PROPERTY_TYPE_INTEGER; aproperty->u.integer = prop->value.integer; } return 0; } return PCF_Err_Invalid_Argument; }
static FT_Error pcf_interpret_style( PCF_Face pcf ) { FT_Error error = PCF_Err_Ok; FT_Face face = FT_FACE( pcf ); FT_Memory memory = face->memory; PCF_Property prop; int nn, len; char* strings[4] = { NULL, NULL, NULL, NULL }; int lengths[4]; face->style_flags = 0; prop = pcf_find_property( pcf, "SLANT" ); if ( prop && prop->isString && ( *(prop->value.atom) == 'O' || *(prop->value.atom) == 'o' || *(prop->value.atom) == 'I' || *(prop->value.atom) == 'i' ) ) { face->style_flags |= FT_STYLE_FLAG_ITALIC; strings[2] = ( *(prop->value.atom) == 'O' || *(prop->value.atom) == 'o' ) ? (char *)"Oblique" : (char *)"Italic"; } prop = pcf_find_property( pcf, "WEIGHT_NAME" ); if ( prop && prop->isString && ( *(prop->value.atom) == 'B' || *(prop->value.atom) == 'b' ) ) { face->style_flags |= FT_STYLE_FLAG_BOLD; strings[1] = (char *)"Bold"; } prop = pcf_find_property( pcf, "SETWIDTH_NAME" ); if ( prop && prop->isString && *(prop->value.atom) && !( *(prop->value.atom) == 'N' || *(prop->value.atom) == 'n' ) ) strings[3] = (char *)(prop->value.atom); prop = pcf_find_property( pcf, "ADD_STYLE_NAME" ); if ( prop && prop->isString && *(prop->value.atom) && !( *(prop->value.atom) == 'N' || *(prop->value.atom) == 'n' ) ) strings[0] = (char *)(prop->value.atom); for ( len = 0, nn = 0; nn < 4; nn++ ) { lengths[nn] = 0; if ( strings[nn] ) { lengths[nn] = ft_strlen( strings[nn] ); len += lengths[nn] + 1; } } if ( len == 0 ) { strings[0] = (char *)"Regular"; lengths[0] = ft_strlen( strings[0] ); len = lengths[0] + 1; } { char* s; if ( FT_ALLOC( face->style_name, len ) ) return error; s = face->style_name; for ( nn = 0; nn < 4; nn++ ) { char* src = strings[nn]; len = lengths[nn]; if ( src == NULL ) continue; /* separate elements with a space */ if ( s != face->style_name ) *s++ = ' '; ft_memcpy( s, src, len ); /* need to convert spaces to dashes for */ /* add_style_name and setwidth_name */ if ( nn == 0 || nn == 3 ) { int mm; for ( mm = 0; mm < len; mm++ ) if (s[mm] == ' ') s[mm] = '-'; } s += len; } *s = 0; } return error; }
pcf_load_font( FT_Stream stream, PCF_Face face ) { FT_Error error = PCF_Err_Ok; FT_Memory memory = FT_FACE(face)->memory; FT_Bool hasBDFAccelerators; error = pcf_read_TOC( stream, face ); if ( error ) goto Exit; error = pcf_get_properties( stream, face ); if ( error ) goto Exit; /* Use the old accelerators if no BDF accelerators are in the file. */ hasBDFAccelerators = pcf_has_table_type( face->toc.tables, face->toc.count, PCF_BDF_ACCELERATORS ); if ( !hasBDFAccelerators ) { error = pcf_get_accel( stream, face, PCF_ACCELERATORS ); if ( error ) goto Exit; } /* metrics */ error = pcf_get_metrics( stream, face ); if ( error ) goto Exit; /* bitmaps */ error = pcf_get_bitmaps( stream, face ); if ( error ) goto Exit; /* encodings */ error = pcf_get_encodings( stream, face ); if ( error ) goto Exit; /* BDF style accelerators (i.e. bounds based on encoded glyphs) */ if ( hasBDFAccelerators ) { error = pcf_get_accel( stream, face, PCF_BDF_ACCELERATORS ); if ( error ) goto Exit; } /* XXX: TO DO: inkmetrics and glyph_names are missing */ /* now construct the face object */ { FT_Face root = FT_FACE( face ); PCF_Property prop; root->num_faces = 1; root->face_index = 0; root->face_flags = FT_FACE_FLAG_FIXED_SIZES | FT_FACE_FLAG_HORIZONTAL | FT_FACE_FLAG_FAST_GLYPHS; if ( face->accel.constantWidth ) root->face_flags |= FT_FACE_FLAG_FIXED_WIDTH; if ( ( error = pcf_interpret_style( face ) ) != 0 ) goto Exit; prop = pcf_find_property( face, "FAMILY_NAME" ); if ( prop && prop->isString ) { if ( FT_STRDUP( root->family_name, prop->value.atom ) ) goto Exit; } else root->family_name = NULL; /* * Note: We shift all glyph indices by +1 since we must * respect the convention that glyph 0 always corresponds * to the `missing glyph'. * * This implies bumping the number of `available' glyphs by 1. */ root->num_glyphs = face->nmetrics + 1; root->num_fixed_sizes = 1; if ( FT_NEW_ARRAY( root->available_sizes, 1 ) ) goto Exit; { FT_Bitmap_Size* bsize = root->available_sizes; FT_Short resolution_x = 0, resolution_y = 0; FT_MEM_ZERO( bsize, sizeof ( FT_Bitmap_Size ) ); #if 0 bsize->height = face->accel.maxbounds.ascent << 6; #endif bsize->height = (FT_Short)( face->accel.fontAscent + face->accel.fontDescent ); prop = pcf_find_property( face, "AVERAGE_WIDTH" ); if ( prop ) bsize->width = (FT_Short)( ( prop->value.integer + 5 ) / 10 ); else bsize->width = (FT_Short)( bsize->height * 2/3 ); prop = pcf_find_property( face, "POINT_SIZE" ); if ( prop ) /* convert from 722.7 decipoints to 72 points per inch */ bsize->size = (FT_Pos)( ( prop->value.integer * 64 * 7200 + 36135L ) / 72270L ); prop = pcf_find_property( face, "PIXEL_SIZE" ); if ( prop ) bsize->y_ppem = (FT_Short)prop->value.integer << 6; prop = pcf_find_property( face, "RESOLUTION_X" ); if ( prop ) resolution_x = (FT_Short)prop->value.integer; prop = pcf_find_property( face, "RESOLUTION_Y" ); if ( prop ) resolution_y = (FT_Short)prop->value.integer; if ( bsize->y_ppem == 0 ) { bsize->y_ppem = bsize->size; if ( resolution_y ) bsize->y_ppem = bsize->y_ppem * resolution_y / 72; } if ( resolution_x && resolution_y ) bsize->x_ppem = bsize->y_ppem * resolution_x / resolution_y; else bsize->x_ppem = bsize->y_ppem; } /* set up charset */ { PCF_Property charset_registry = 0, charset_encoding = 0; charset_registry = pcf_find_property( face, "CHARSET_REGISTRY" ); charset_encoding = pcf_find_property( face, "CHARSET_ENCODING" ); if ( charset_registry && charset_registry->isString && charset_encoding && charset_encoding->isString ) { if ( FT_STRDUP( face->charset_encoding, charset_encoding->value.atom ) || FT_STRDUP( face->charset_registry, charset_registry->value.atom ) ) goto Exit; } } } Exit: if ( error ) { /* This is done to respect the behaviour of the original */ /* PCF font driver. */ error = PCF_Err_Invalid_File_Format; } return error; }
pcf_load_font( FT_Stream stream, PCF_Face face ) { FT_Error error = PCF_Err_Ok; FT_Memory memory = FT_FACE(face)->memory; FT_Bool hasBDFAccelerators; error = pcf_read_TOC( stream, face ); if ( error ) goto Exit; error = pcf_get_properties( stream, face ); if ( error ) goto Exit; /* Use the old accelerators if no BDF accelerators are in the file. */ hasBDFAccelerators = pcf_has_table_type( face->toc.tables, face->toc.count, PCF_BDF_ACCELERATORS ); if ( !hasBDFAccelerators ) { error = pcf_get_accel( stream, face, PCF_ACCELERATORS ); if ( error ) goto Exit; } /* metrics */ error = pcf_get_metrics( stream, face ); if ( error ) goto Exit; /* bitmaps */ error = pcf_get_bitmaps( stream, face ); if ( error ) goto Exit; /* encodings */ error = pcf_get_encodings( stream, face ); if ( error ) goto Exit; /* BDF style accelerators (i.e. bounds based on encoded glyphs) */ if ( hasBDFAccelerators ) { error = pcf_get_accel( stream, face, PCF_BDF_ACCELERATORS ); if ( error ) goto Exit; } /* XXX: TO DO: inkmetrics and glyph_names are missing */ /* now construct the face object */ { FT_Face root = FT_FACE( face ); PCF_Property prop; int size_set = 0; root->num_faces = 1; root->face_index = 0; root->face_flags = FT_FACE_FLAG_FIXED_SIZES | FT_FACE_FLAG_HORIZONTAL | FT_FACE_FLAG_FAST_GLYPHS; 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) == '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' ) 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"; prop = pcf_find_property( face, "FAMILY_NAME" ); if ( prop != NULL ) { if ( prop->isString ) { int l = ft_strlen( prop->value.atom ) + 1; if ( FT_NEW_ARRAY( root->family_name, l ) ) goto Exit; ft_strcpy( root->family_name, prop->value.atom ); } } else root->family_name = 0; root->num_glyphs = face->nmetrics; root->num_fixed_sizes = 1; if ( FT_NEW_ARRAY( root->available_sizes, 1 ) ) goto Exit; prop = pcf_find_property( face, "PIXEL_SIZE" ); if ( prop != NULL ) { root->available_sizes->height = root->available_sizes->width = (FT_Short)( prop->value.integer ); size_set = 1; } else { prop = pcf_find_property( face, "POINT_SIZE" ); if ( prop != NULL ) { PCF_Property xres, yres, avgw; xres = pcf_find_property( face, "RESOLUTION_X" ); yres = pcf_find_property( face, "RESOLUTION_Y" ); avgw = pcf_find_property( face, "AVERAGE_WIDTH" ); if ( ( yres != NULL ) && ( xres != NULL ) ) { root->available_sizes->height = (FT_Short)( prop->value.integer * yres->value.integer / 720 ); root->available_sizes->width = (FT_Short)( prop->value.integer * xres->value.integer / 720 ); size_set = 1; } } } if (size_set == 0 ) { root->available_sizes->width = 12; root->available_sizes->height = 12; } /* set-up charset */ { PCF_Property charset_registry = 0, charset_encoding = 0; charset_registry = pcf_find_property( face, "CHARSET_REGISTRY" ); charset_encoding = pcf_find_property( face, "CHARSET_ENCODING" ); if ( ( charset_registry != NULL ) && ( charset_encoding != NULL ) ) { if ( ( charset_registry->isString ) && ( charset_encoding->isString ) ) { if ( FT_NEW_ARRAY( face->charset_encoding, ft_strlen( charset_encoding->value.atom ) + 1 ) ) goto Exit; if ( FT_NEW_ARRAY( face->charset_registry, ft_strlen( charset_registry->value.atom ) + 1 ) ) goto Exit; ft_strcpy( face->charset_registry, charset_registry->value.atom ); ft_strcpy( face->charset_encoding, charset_encoding->value.atom ); } } } } Exit: if ( error ) { /* this is done to respect the behaviour of the original */ /* PCF font driver. */ error = PCF_Err_Invalid_File_Format; } return error; }
static FT_Error pcf_interpret_style( PCF_Face pcf ) { FT_Error error = PCF_Err_Ok; FT_Face face = FT_FACE( pcf ); FT_Memory memory = face->memory; PCF_Property prop; char *istr = NULL, *bstr = NULL; char *sstr = NULL, *astr = NULL; int parts = 0, len = 0; face->style_flags = 0; prop = pcf_find_property( pcf, "SLANT" ); if ( prop && prop->isString && ( *(prop->value.atom) == 'O' || *(prop->value.atom) == 'o' || *(prop->value.atom) == 'I' || *(prop->value.atom) == 'i' ) ) { face->style_flags |= FT_STYLE_FLAG_ITALIC; istr = ( *(prop->value.atom) == 'O' || *(prop->value.atom) == 'o' ) ? (char *)"Oblique" : (char *)"Italic"; len += ft_strlen( istr ); parts++; } prop = pcf_find_property( pcf, "WEIGHT_NAME" ); if ( prop && prop->isString && ( *(prop->value.atom) == 'B' || *(prop->value.atom) == 'b' ) ) { face->style_flags |= FT_STYLE_FLAG_BOLD; bstr = (char *)"Bold"; len += ft_strlen( bstr ); parts++; } prop = pcf_find_property( pcf, "SETWIDTH_NAME" ); if ( prop && prop->isString && *(prop->value.atom) && !( *(prop->value.atom) == 'N' || *(prop->value.atom) == 'n' ) ) { sstr = (char *)(prop->value.atom); len += ft_strlen( sstr ); parts++; } prop = pcf_find_property( pcf, "ADD_STYLE_NAME" ); if ( prop && prop->isString && *(prop->value.atom) && !( *(prop->value.atom) == 'N' || *(prop->value.atom) == 'n' ) ) { astr = (char *)(prop->value.atom); len += ft_strlen( astr ); parts++; } if ( !parts || !len ) face->style_name = (char *)"Regular"; else { char *style, *s; unsigned int i; if ( FT_ALLOC( style, len + parts ) ) return error; s = style; if ( astr ) { ft_strcpy( s, astr ); for ( i = 0; i < ft_strlen( astr ); i++, s++ ) if ( *s == ' ' ) *s = '-'; /* replace spaces with dashes */ *(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 ); for ( i = 0; i < ft_strlen( sstr ); i++, s++ ) if ( *s == ' ' ) *s = '-'; /* replace spaces with dashes */ *(s++) = ' '; } *(--s) = '\0'; /* overwrite last ' ', terminate the string */ face->style_name = style; /* allocated string */ } return error; }
pcf_load_font( FT_Stream stream, PCF_Face face ) { FT_Error error = PCF_Err_Ok; FT_Memory memory = FT_FACE(face)->memory; FT_Bool hasBDFAccelerators; error = pcf_read_TOC( stream, face ); if ( error ) goto Exit; error = pcf_get_properties( stream, face ); if ( error ) goto Exit; /* Use the old accelerators if no BDF accelerators are in the file. */ hasBDFAccelerators = pcf_has_table_type( face->toc.tables, face->toc.count, PCF_BDF_ACCELERATORS ); if ( !hasBDFAccelerators ) { error = pcf_get_accel( stream, face, PCF_ACCELERATORS ); if ( error ) goto Exit; } /* metrics */ error = pcf_get_metrics( stream, face ); if ( error ) goto Exit; /* bitmaps */ error = pcf_get_bitmaps( stream, face ); if ( error ) goto Exit; /* encodings */ error = pcf_get_encodings( stream, face ); if ( error ) goto Exit; /* BDF style accelerators (i.e. bounds based on encoded glyphs) */ if ( hasBDFAccelerators ) { error = pcf_get_accel( stream, face, PCF_BDF_ACCELERATORS ); if ( error ) goto Exit; } /* XXX: TO DO: inkmetrics and glyph_names are missing */ /* now construct the face object */ { FT_Face root = FT_FACE( face ); PCF_Property prop; root->num_faces = 1; root->face_index = 0; root->face_flags = FT_FACE_FLAG_FIXED_SIZES | FT_FACE_FLAG_HORIZONTAL | FT_FACE_FLAG_FAST_GLYPHS; 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"; prop = pcf_find_property( face, "FAMILY_NAME" ); if ( prop != NULL ) { if ( prop->isString ) { int l = ft_strlen( prop->value.atom ) + 1; if ( FT_NEW_ARRAY( root->family_name, l ) ) goto Exit; ft_strcpy( root->family_name, prop->value.atom ); } } else root->family_name = 0; /* Note: We shift all glyph indices by +1 since we must * respect the convention that glyph 0 always corresponds * to the "missing glyph". * * This implies bumping the number of "available" glyphs by 1. */ root->num_glyphs = face->nmetrics + 1; root->num_fixed_sizes = 1; if ( FT_NEW_ARRAY( root->available_sizes, 1 ) ) goto Exit; { FT_Bitmap_Size* bsize = root->available_sizes; FT_MEM_ZERO( bsize, sizeof ( FT_Bitmap_Size ) ); prop = pcf_find_property( face, "PIXEL_SIZE" ); if ( prop != NULL ) bsize->height = (FT_Short)prop->value.integer; prop = pcf_find_property( face, "AVERAGE_WIDTH" ); if ( prop != NULL ) bsize->width = (FT_Short)( ( prop->value.integer + 5 ) / 10 ); prop = pcf_find_property( face, "POINT_SIZE" ); if ( prop != NULL ) /* convert from 722,7 decipoints to 72 points per inch */ bsize->size = (FT_Pos)( ( prop->value.integer * 64 * 7200 + 36135L ) / 72270L ); prop = pcf_find_property( face, "RESOLUTION_X" ); if ( prop != NULL ) bsize->x_ppem = (FT_Pos)( ( prop->value.integer * bsize->size + 36 ) / 72 ); prop = pcf_find_property( face, "RESOLUTION_Y" ); if ( prop != NULL ) bsize->y_ppem = (FT_Pos)( ( prop->value.integer * bsize->size + 36 ) / 72 ); if ( bsize->height == 0 ) bsize->height = (FT_Short)( ( bsize->y_ppem + 32 ) / 64 ); if ( bsize->height == 0 ) bsize->height = 12; } /* set up charset */ { PCF_Property charset_registry = 0, charset_encoding = 0; charset_registry = pcf_find_property( face, "CHARSET_REGISTRY" ); charset_encoding = pcf_find_property( face, "CHARSET_ENCODING" ); if ( ( charset_registry != NULL ) && ( charset_encoding != NULL ) ) { if ( ( charset_registry->isString ) && ( charset_encoding->isString ) ) { if ( FT_NEW_ARRAY( face->charset_encoding, ft_strlen( charset_encoding->value.atom ) + 1 ) ) goto Exit; if ( FT_NEW_ARRAY( face->charset_registry, ft_strlen( charset_registry->value.atom ) + 1 ) ) goto Exit; ft_strcpy( face->charset_registry, charset_registry->value.atom ); ft_strcpy( face->charset_encoding, charset_encoding->value.atom ); } } } } Exit: if ( error ) { /* this is done to respect the behaviour of the original */ /* PCF font driver. */ error = PCF_Err_Invalid_File_Format; } return error; }