static FT_Bool _tt_check_patents_in_range( FT_Stream stream, FT_ULong size ) { FT_Bool result = FALSE; FT_Error error; FT_Bytes p, end; if ( FT_FRAME_ENTER( size ) ) return 0; p = stream->cursor; end = p + size; while ( p < end ) { switch (p[0]) { case 0x06: /* SPvTL // */ case 0x07: /* SPvTL + */ case 0x08: /* SFvTL // */ case 0x09: /* SFvTL + */ case 0x0A: /* SPvFS */ case 0x0B: /* SFvFS */ result = TRUE; goto Exit; case 0x40: if ( p + 1 >= end ) goto Exit; p += p[1] + 2; break; case 0x41: if ( p + 1 >= end ) goto Exit; p += p[1] * 2 + 2; break; case 0x71: /* DELTAP2 */ case 0x72: /* DELTAP3 */ case 0x73: /* DELTAC0 */ case 0x74: /* DELTAC1 */ case 0x75: /* DELTAC2 */ result = TRUE; goto Exit; case 0xB0: case 0xB1: case 0xB2: case 0xB3: case 0xB4: case 0xB5: case 0xB6: case 0xB7: p += ( p[0] - 0xB0 ) + 2; break; case 0xB8: case 0xB9: case 0xBA: case 0xBB: case 0xBC: case 0xBD: case 0xBE: case 0xBF: p += ( p[0] - 0xB8 ) * 2 + 3; break; default: p += 1; break; } } Exit: FT_UNUSED( error ); FT_FRAME_EXIT(); return result; }
pfr_face_init( FT_Stream stream, FT_Face pfrface, FT_Int face_index, FT_Int num_params, FT_Parameter* params ) { PFR_Face face = (PFR_Face)pfrface; FT_Error error; FT_UNUSED( num_params ); FT_UNUSED( params ); /* load the header and check it */ error = pfr_header_load( &face->header, stream ); if ( error ) goto Exit; if ( !pfr_header_check( &face->header ) ) { FT_TRACE4(( "pfr_face_init: not a valid PFR font\n" )); error = PFR_Err_Unknown_File_Format; goto Exit; } /* check face index */ { FT_UInt num_faces; error = pfr_log_font_count( stream, face->header.log_dir_offset, &num_faces ); if ( error ) goto Exit; pfrface->num_faces = num_faces; } if ( face_index < 0 ) goto Exit; if ( face_index >= pfrface->num_faces ) { FT_ERROR(( "pfr_face_init: invalid face index\n" )); error = PFR_Err_Invalid_Argument; goto Exit; } /* load the face */ error = pfr_log_font_load( &face->log_font, stream, face_index, face->header.log_dir_offset, FT_BOOL( face->header.phy_font_max_size_high != 0 ) ); if ( error ) goto Exit; /* now load the physical font descriptor */ error = pfr_phy_font_load( &face->phy_font, stream, face->log_font.phys_offset, face->log_font.phys_size ); if ( error ) goto Exit; /* now, set-up all root face fields */ { PFR_PhyFont phy_font = &face->phy_font; pfrface->face_index = face_index; pfrface->num_glyphs = phy_font->num_chars; pfrface->face_flags = FT_FACE_FLAG_SCALABLE; if ( (phy_font->flags & PFR_PHY_PROPORTIONAL) == 0 ) pfrface->face_flags |= FT_FACE_FLAG_FIXED_WIDTH; if ( phy_font->flags & PFR_PHY_VERTICAL ) pfrface->face_flags |= FT_FACE_FLAG_VERTICAL; else pfrface->face_flags |= FT_FACE_FLAG_HORIZONTAL; if ( phy_font->num_strikes > 0 ) pfrface->face_flags |= FT_FACE_FLAG_FIXED_SIZES; if ( phy_font->num_kern_pairs > 0 ) pfrface->face_flags |= FT_FACE_FLAG_KERNING; /* If no family name was found in the "undocumented" auxiliary * data, use the font ID instead. This sucks but is better than * nothing. */ pfrface->family_name = phy_font->family_name; if ( pfrface->family_name == NULL ) pfrface->family_name = phy_font->font_id; /* note that the style name can be NULL in certain PFR fonts, * probably meaning "Regular" */ pfrface->style_name = phy_font->style_name; pfrface->num_fixed_sizes = 0; pfrface->available_sizes = 0; pfrface->bbox = phy_font->bbox; pfrface->units_per_EM = (FT_UShort)phy_font->outline_resolution; pfrface->ascender = (FT_Short) phy_font->bbox.yMax; pfrface->descender = (FT_Short) phy_font->bbox.yMin; pfrface->height = (FT_Short)( ( ( pfrface->ascender - pfrface->descender ) * 12 ) / 10 ); if ( phy_font->num_strikes > 0 ) { FT_UInt n, count = phy_font->num_strikes; FT_Bitmap_Size* size; PFR_Strike strike; FT_Memory memory = pfrface->stream->memory; if ( FT_NEW_ARRAY( pfrface->available_sizes, count ) ) goto Exit; size = pfrface->available_sizes; strike = phy_font->strikes; for ( n = 0; n < count; n++, size++, strike++ ) { size->height = (FT_UShort)strike->y_ppm; size->width = (FT_UShort)strike->x_ppm; } pfrface->num_fixed_sizes = count; } /* now compute maximum advance width */ if ( ( phy_font->flags & PFR_PHY_PROPORTIONAL ) == 0 ) pfrface->max_advance_width = (FT_Short)phy_font->standard_advance; else { FT_Int max = 0; FT_UInt count = phy_font->num_chars; PFR_Char gchar = phy_font->chars; for ( ; count > 0; count--, gchar++ ) { if ( max < gchar->advance ) max = gchar->advance; } pfrface->max_advance_width = (FT_Short)max; } pfrface->max_advance_height = pfrface->height; pfrface->underline_position = (FT_Short)( -pfrface->units_per_EM / 10 ); pfrface->underline_thickness = (FT_Short)( pfrface->units_per_EM / 30 ); /* create charmap */ { FT_CharMapRec charmap; charmap.face = pfrface; charmap.platform_id = 3; charmap.encoding_id = 1; charmap.encoding = FT_ENCODING_UNICODE; FT_CMap_New( &pfr_cmap_class_rec, NULL, &charmap, NULL ); #if 0 /* Select default charmap */ if ( pfrface->num_charmaps ) pfrface->charmap = pfrface->charmaps[0]; #endif } /* check whether we've loaded any kerning pairs */ if ( phy_font->num_kern_pairs ) pfrface->face_flags |= FT_FACE_FLAG_KERNING; } Exit: return error; }
static FT_Error PCF_Glyph_Load( FT_GlyphSlot slot, FT_Size size, FT_UInt glyph_index, FT_Int32 load_flags ) { PCF_Face face = (PCF_Face)FT_SIZE_FACE( size ); FT_Stream stream = face->root.stream; FT_Error error = PCF_Err_Ok; FT_Bitmap* bitmap = &slot->bitmap; PCF_Metric metric; int bytes; FT_UNUSED( load_flags ); FT_TRACE4(( "load_glyph %d ---", glyph_index )); if ( !face ) { error = PCF_Err_Invalid_Argument; goto Exit; } if ( glyph_index > 0 ) glyph_index--; metric = face->metrics + glyph_index; bitmap->rows = metric->ascent + metric->descent; bitmap->width = metric->rightSideBearing - metric->leftSideBearing; bitmap->num_grays = 1; bitmap->pixel_mode = FT_PIXEL_MODE_MONO; FT_TRACE6(( "BIT_ORDER %d ; BYTE_ORDER %d ; GLYPH_PAD %d\n", PCF_BIT_ORDER( face->bitmapsFormat ), PCF_BYTE_ORDER( face->bitmapsFormat ), PCF_GLYPH_PAD( face->bitmapsFormat ) )); switch ( PCF_GLYPH_PAD( face->bitmapsFormat ) ) { case 1: bitmap->pitch = ( bitmap->width + 7 ) >> 3; break; case 2: bitmap->pitch = ( ( bitmap->width + 15 ) >> 4 ) << 1; break; case 4: bitmap->pitch = ( ( bitmap->width + 31 ) >> 5 ) << 2; break; case 8: bitmap->pitch = ( ( bitmap->width + 63 ) >> 6 ) << 3; break; default: return PCF_Err_Invalid_File_Format; } /* XXX: to do: are there cases that need repadding the bitmap? */ bytes = bitmap->pitch * bitmap->rows; error = ft_glyphslot_alloc_bitmap( slot, bytes ); if ( error ) goto Exit; if ( FT_STREAM_SEEK( metric->bits ) || FT_STREAM_READ( bitmap->buffer, bytes ) ) goto Exit; if ( PCF_BIT_ORDER( face->bitmapsFormat ) != MSBFirst ) BitOrderInvert( bitmap->buffer, bytes ); if ( ( PCF_BYTE_ORDER( face->bitmapsFormat ) != PCF_BIT_ORDER( face->bitmapsFormat ) ) ) { switch ( PCF_SCAN_UNIT( face->bitmapsFormat ) ) { case 1: break; case 2: TwoByteSwap( bitmap->buffer, bytes ); break; case 4: FourByteSwap( bitmap->buffer, bytes ); break; } } slot->bitmap_left = metric->leftSideBearing; slot->bitmap_top = metric->ascent; slot->metrics.horiAdvance = metric->characterWidth << 6; slot->metrics.horiBearingX = metric->leftSideBearing << 6; slot->metrics.horiBearingY = metric->ascent << 6; slot->metrics.width = ( metric->rightSideBearing - metric->leftSideBearing ) << 6; slot->metrics.height = bitmap->rows << 6; slot->linearHoriAdvance = (FT_Fixed)bitmap->width << 16; slot->format = FT_GLYPH_FORMAT_BITMAP; FT_TRACE4(( " --- ok\n" )); Exit: return error; }
T1_Driver_Done( T1_Driver driver ) { FT_UNUSED( driver ); }
static FT_Error FNT_Face_Init( FT_Stream stream, FNT_Face face, FT_Int face_index, FT_Int num_params, FT_Parameter* params ) { FT_Error error; FT_Memory memory = FT_FACE_MEMORY( face ); FT_UNUSED( num_params ); FT_UNUSED( params ); /* try to load font from a DLL */ error = fnt_face_get_dll_font( face, face_index ); if ( error ) { /* this didn't work; try to load a single FNT font */ FNT_Font font; if ( FT_NEW( face->font ) ) goto Exit; face->root.num_faces = 1; font = face->font; font->offset = 0; font->fnt_size = stream->size; error = fnt_font_load( font, stream ); if ( error ) goto Fail; } /* we now need to fill the root FT_Face fields */ /* with relevant information */ { FT_Face root = FT_FACE( face ); FNT_Font font = face->font; root->face_flags = FT_FACE_FLAG_FIXED_SIZES | FT_FACE_FLAG_HORIZONTAL; if ( font->header.avg_width == font->header.max_width ) root->face_flags |= FT_FACE_FLAG_FIXED_WIDTH; if ( font->header.italic ) root->style_flags |= FT_STYLE_FLAG_ITALIC; if ( font->header.weight >= 800 ) root->style_flags |= FT_STYLE_FLAG_BOLD; /* set up the `fixed_sizes' array */ if ( FT_NEW_ARRAY( root->available_sizes, 1 ) ) goto Fail; root->num_fixed_sizes = 1; { FT_Bitmap_Size* bsize = root->available_sizes; bsize->width = font->header.avg_width; bsize->height = font->header.pixel_height + font->header.external_leading; bsize->size = font->header.nominal_point_size << 6; bsize->x_ppem = (FT_Pos)( ( font->header.horizontal_resolution * bsize->size + 36 ) / 72 ); bsize->y_ppem = (FT_Pos)( ( font->header.vertical_resolution* bsize->size + 36 ) / 72 ); } { FT_CharMapRec charmap; charmap.encoding = FT_ENCODING_UNICODE; charmap.platform_id = 3; charmap.encoding_id = 1; charmap.face = root; error = FT_CMap_New( fnt_cmap_class, NULL, &charmap, NULL ); if ( error ) goto Fail; /* Select default charmap */ if ( root->num_charmaps ) root->charmap = root->charmaps[0]; } /* setup remaining flags */ /* reserve one slot for the .notdef glyph at index 0 */ root->num_glyphs = font->header.last_char - font->header.first_char + 1 + 1; root->family_name = (FT_String*)font->fnt_frame + font->header.face_name_offset; 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"; } Fail: if ( error ) FNT_Face_Done( face ); Exit: return error; }
cff_driver_done( FT_Module module ) { FT_UNUSED( module ); }
T1_Face_Init( FT_Stream stream, T1_Face face, FT_Int face_index, FT_Int num_params, FT_Parameter* params ) { FT_Error error; FT_Service_PsCMaps psnames; PSAux_Service psaux; T1_Font type1 = &face->type1; PS_FontInfo info = &type1->font_info; FT_UNUSED( num_params ); FT_UNUSED( params ); FT_UNUSED( face_index ); FT_UNUSED( stream ); face->root.num_faces = 1; FT_FACE_FIND_GLOBAL_SERVICE( face, psnames, POSTSCRIPT_CMAPS ); face->psnames = psnames; face->psaux = FT_Get_Module_Interface( FT_FACE_LIBRARY( face ), "psaux" ); psaux = (PSAux_Service)face->psaux; face->pshinter = FT_Get_Module_Interface( FT_FACE_LIBRARY( face ), "pshinter" ); /* open the tokenizer; this will also check the font format */ error = T1_Open_Face( face ); if ( error ) goto Exit; /* if we just wanted to check the format, leave successfully now */ if ( face_index < 0 ) goto Exit; /* check the face index */ if ( face_index != 0 ) { FT_ERROR(( "T1_Face_Init: invalid face index\n" )); error = T1_Err_Invalid_Argument; goto Exit; } /* now load the font program into the face object */ /* initialize the face object fields */ /* set up root face fields */ { FT_Face root = (FT_Face)&face->root; root->num_glyphs = type1->num_glyphs; root->face_index = face_index; root->face_flags = FT_FACE_FLAG_SCALABLE; root->face_flags |= FT_FACE_FLAG_HORIZONTAL; root->face_flags |= FT_FACE_FLAG_GLYPH_NAMES; if ( info->is_fixed_pitch ) root->face_flags |= FT_FACE_FLAG_FIXED_WIDTH; if ( face->blend ) root->face_flags |= FT_FACE_FLAG_MULTIPLE_MASTERS; /* XXX: TODO -- add kerning with .afm support */ /* get style name -- be careful, some broken fonts only */ /* have a `/FontName' dictionary entry! */ root->family_name = info->family_name; /* assume "Regular" style if we don't know better */ root->style_name = (char *)"Regular"; if ( root->family_name ) { char* full = info->full_name; char* family = root->family_name; if ( full ) { while ( *full ) { if ( *full == *family ) { family++; full++; } else { if ( *full == ' ' || *full == '-' ) full++; else if ( *family == ' ' || *family == '-' ) family++; else { if ( !*family ) root->style_name = full; break; } } } } } else { /* do we have a `/FontName'? */ if ( type1->font_name ) root->family_name = type1->font_name; } /* compute style flags */ root->style_flags = 0; if ( info->italic_angle ) root->style_flags |= FT_STYLE_FLAG_ITALIC; if ( info->weight ) { if ( !ft_strcmp( info->weight, "Bold" ) || !ft_strcmp( info->weight, "Black" ) ) root->style_flags |= FT_STYLE_FLAG_BOLD; } /* no embedded bitmap support */ root->num_fixed_sizes = 0; root->available_sizes = 0; root->bbox.xMin = type1->font_bbox.xMin >> 16; root->bbox.yMin = type1->font_bbox.yMin >> 16; root->bbox.xMax = ( type1->font_bbox.xMax + 0xFFFFU ) >> 16; root->bbox.yMax = ( type1->font_bbox.yMax + 0xFFFFU ) >> 16; /* Set units_per_EM if we didn't set it in parse_font_matrix. */ if ( !root->units_per_EM ) root->units_per_EM = 1000; root->ascender = (FT_Short)( root->bbox.yMax ); root->descender = (FT_Short)( root->bbox.yMin ); root->height = (FT_Short)( ( ( root->ascender - root->descender ) * 12 ) / 10 ); /* now compute the maximum advance width */ root->max_advance_width = (FT_Short)( root->bbox.xMax ); { FT_Pos max_advance; error = T1_Compute_Max_Advance( face, &max_advance ); /* in case of error, keep the standard width */ if ( !error ) root->max_advance_width = (FT_Short)max_advance; else error = 0; /* clear error */ } root->max_advance_height = root->height; root->underline_position = (FT_Short)info->underline_position; root->underline_thickness = (FT_Short)info->underline_thickness; root->internal->max_points = 0; root->internal->max_contours = 0; } { FT_Face root = &face->root; if ( psnames && psaux ) { FT_CharMapRec charmap; T1_CMap_Classes cmap_classes = psaux->t1_cmap_classes; FT_CMap_Class clazz; charmap.face = root; /* first of all, try to synthetize a Unicode charmap */ charmap.platform_id = 3; charmap.encoding_id = 1; charmap.encoding = FT_ENCODING_UNICODE; FT_CMap_New( cmap_classes->unicode, NULL, &charmap, NULL ); /* now, generate an Adobe Standard encoding when appropriate */ charmap.platform_id = 7; clazz = NULL; switch ( type1->encoding_type ) { case T1_ENCODING_TYPE_STANDARD: charmap.encoding = FT_ENCODING_ADOBE_STANDARD; charmap.encoding_id = TT_ADOBE_ID_STANDARD; clazz = cmap_classes->standard; break; case T1_ENCODING_TYPE_EXPERT: charmap.encoding = FT_ENCODING_ADOBE_EXPERT; charmap.encoding_id = TT_ADOBE_ID_EXPERT; clazz = cmap_classes->expert; break; case T1_ENCODING_TYPE_ARRAY: charmap.encoding = FT_ENCODING_ADOBE_CUSTOM; charmap.encoding_id = TT_ADOBE_ID_CUSTOM; clazz = cmap_classes->custom; break; case T1_ENCODING_TYPE_ISOLATIN1: charmap.encoding = FT_ENCODING_ADOBE_LATIN_1; charmap.encoding_id = TT_ADOBE_ID_LATIN_1; clazz = cmap_classes->unicode; break; default: ; } if ( clazz ) FT_CMap_New( clazz, NULL, &charmap, NULL ); #if 0 /* Select default charmap */ if (root->num_charmaps) root->charmap = root->charmaps[0]; #endif } } Exit: return error; }
PCF_Face_Init( FT_Stream stream, FT_Face pcfface, /* PCF_Face */ FT_Int face_index, FT_Int num_params, FT_Parameter* params ) { PCF_Face face = (PCF_Face)pcfface; FT_Error error = PCF_Err_Ok; FT_UNUSED( num_params ); FT_UNUSED( params ); FT_UNUSED( face_index ); error = pcf_load_font( stream, face ); if ( error ) { FT_Error error2; PCF_Face_Done( pcfface ); /* this didn't work, try gzip support! */ error2 = FT_Stream_OpenGzip( &face->gzip_stream, stream ); if ( FT_ERROR_BASE( error2 ) == FT_Err_Unimplemented_Feature ) goto Fail; error = error2; if ( error ) #ifdef FT_CONFIG_OPTION_USE_LZW { FT_Error error3; /* this didn't work, try LZW support! */ error3 = FT_Stream_OpenLZW( &face->gzip_stream, stream ); if ( FT_ERROR_BASE( error3 ) == FT_Err_Unimplemented_Feature ) goto Fail; error = error3; if ( error ) goto Fail; face->gzip_source = stream; pcfface->stream = &face->gzip_stream; stream = pcfface->stream; error = pcf_load_font( stream, face ); if ( error ) goto Fail; } #else goto Fail; #endif else { face->gzip_source = stream; pcfface->stream = &face->gzip_stream; stream = pcfface->stream; error = pcf_load_font( stream, face ); if ( error ) goto Fail; } }
static void psh_blues_set_zones_0( PSH_Blues target, FT_Bool is_others, FT_UInt read_count, FT_Short* read, PSH_Blue_Table top_table, PSH_Blue_Table bot_table ) { FT_UInt count_top = top_table->count; FT_UInt count_bot = bot_table->count; FT_Bool first = 1; FT_UNUSED( target ); for ( ; read_count > 0; read_count -= 2 ) { FT_Int reference, delta; FT_UInt count; PSH_Blue_Zone zones, zone; FT_Bool top; /* read blue zone entry, and select target top/bottom zone */ top = 0; if ( first || is_others ) { reference = read[1]; delta = read[0] - reference; zones = bot_table->zones; count = count_bot; first = 0; } else { reference = read[0]; delta = read[1] - reference; zones = top_table->zones; count = count_top; top = 1; } /* insert into sorted table */ zone = zones; for ( ; count > 0; count--, zone++ ) { if ( reference < zone->org_ref ) break; if ( reference == zone->org_ref ) { FT_Int delta0 = zone->org_delta; /* we have two zones on the same reference position -- */ /* only keep the largest one */ if ( delta < 0 ) { if ( delta < delta0 ) zone->org_delta = delta; } else { if ( delta > delta0 ) zone->org_delta = delta; } goto Skip; } } for ( ; count > 0; count-- ) zone[count] = zone[count-1]; zone->org_ref = reference; zone->org_delta = delta; if ( top ) count_top++; else count_bot++; Skip: read += 2; } top_table->count = count_top; bot_table->count = count_bot; }
static FT_Error pcf_get_bitmaps( FT_Stream stream, PCF_Face face ) { FT_Error error = PCF_Err_Ok; FT_Memory memory = FT_FACE(face)->memory; FT_Long* offsets; FT_Long bitmapSizes[GLYPHPADOPTIONS]; FT_ULong format, size; int nbitmaps, i, sizebitmaps = 0; char* bitmaps; error = pcf_seek_to_table_type( stream, face->toc.tables, face->toc.count, PCF_BITMAPS, &format, &size ); if ( error ) return error; error = FT_Stream_EnterFrame( stream, 8 ); if ( error ) return error; format = FT_GET_ULONG_LE(); if ( PCF_BYTE_ORDER( format ) == MSBFirst ) nbitmaps = FT_GET_ULONG(); else nbitmaps = FT_GET_ULONG_LE(); FT_Stream_ExitFrame( stream ); if ( !PCF_FORMAT_MATCH( format, PCF_DEFAULT_FORMAT ) ) return PCF_Err_Invalid_File_Format; if ( nbitmaps != face->nmetrics ) return PCF_Err_Invalid_File_Format; if ( FT_NEW_ARRAY( offsets, nbitmaps ) ) return error; FT_TRACE4(( "pcf_get_bitmaps:\n" )); for ( i = 0; i < nbitmaps; i++ ) { if ( PCF_BYTE_ORDER( format ) == MSBFirst ) (void)FT_READ_LONG( offsets[i] ); else (void)FT_READ_LONG_LE( offsets[i] ); FT_TRACE4(( " bitmap %d: offset %ld (0x%lX)\n", i, offsets[i], offsets[i] )); } if ( error ) goto Bail; for ( i = 0; i < GLYPHPADOPTIONS; i++ ) { if ( PCF_BYTE_ORDER( format ) == MSBFirst ) (void)FT_READ_LONG( bitmapSizes[i] ); else (void)FT_READ_LONG_LE( bitmapSizes[i] ); if ( error ) goto Bail; sizebitmaps = bitmapSizes[PCF_GLYPH_PAD_INDEX( format )]; FT_TRACE4(( " padding %d implies a size of %ld\n", i, bitmapSizes[i] )); } FT_TRACE4(( " %d bitmaps, padding index %ld\n", nbitmaps, PCF_GLYPH_PAD_INDEX( format ) )); FT_TRACE4(( " bitmap size = %d\n", sizebitmaps )); FT_UNUSED( sizebitmaps ); /* only used for debugging */ for ( i = 0; i < nbitmaps; i++ ) face->metrics[i].bits = stream->pos + offsets[i]; face->bitmapsFormat = format; FT_FREE ( offsets ); return error; Bail: FT_FREE ( offsets ); FT_FREE ( bitmaps ); return error; }
FT_Face_CheckTrueTypePatents( FT_Face face ) { FT_UNUSED( face ); return FALSE; }
T1_Driver_Done( FT_Module driver ) { FT_UNUSED( driver ); }
T1_Driver_Init( FT_Module driver ) { FT_UNUSED( driver ); return FT_Err_Ok; }
T1_Face_Init( FT_Stream stream, FT_Face t1face, /* T1_Face */ FT_Int face_index, FT_Int num_params, FT_Parameter* params ) { T1_Face face = (T1_Face)t1face; FT_Error error; FT_Service_PsCMaps psnames; PSAux_Service psaux; T1_Font type1 = &face->type1; PS_FontInfo info = &type1->font_info; FT_UNUSED( num_params ); FT_UNUSED( params ); FT_UNUSED( stream ); face->root.num_faces = 1; FT_FACE_FIND_GLOBAL_SERVICE( face, psnames, POSTSCRIPT_CMAPS ); face->psnames = psnames; face->psaux = FT_Get_Module_Interface( FT_FACE_LIBRARY( face ), "psaux" ); psaux = (PSAux_Service)face->psaux; if ( !psaux ) { FT_ERROR(( "T1_Face_Init: cannot access `psaux' module\n" )); error = FT_THROW( Missing_Module ); goto Exit; } face->pshinter = FT_Get_Module_Interface( FT_FACE_LIBRARY( face ), "pshinter" ); FT_TRACE2(( "Type 1 driver\n" )); /* open the tokenizer; this will also check the font format */ error = T1_Open_Face( face ); if ( error ) goto Exit; /* if we just wanted to check the format, leave successfully now */ if ( face_index < 0 ) goto Exit; /* check the face index */ if ( ( face_index & 0xFFFF ) > 0 ) { FT_ERROR(( "T1_Face_Init: invalid face index\n" )); error = FT_THROW( Invalid_Argument ); goto Exit; } /* now load the font program into the face object */ /* initialize the face object fields */ /* set up root face fields */ { FT_Face root = (FT_Face)&face->root; root->num_glyphs = type1->num_glyphs; root->face_index = 0; root->face_flags |= FT_FACE_FLAG_SCALABLE | FT_FACE_FLAG_HORIZONTAL | FT_FACE_FLAG_GLYPH_NAMES | FT_FACE_FLAG_HINTER; if ( info->is_fixed_pitch ) root->face_flags |= FT_FACE_FLAG_FIXED_WIDTH; if ( face->blend ) root->face_flags |= FT_FACE_FLAG_MULTIPLE_MASTERS; /* The following code to extract the family and the style is very */ /* simplistic and might get some things wrong. For a full-featured */ /* algorithm you might have a look at the whitepaper given at */ /* */ /* http://blogs.msdn.com/text/archive/2007/04/23/wpf-font-selection-model.aspx */ /* get style name -- be careful, some broken fonts only */ /* have a `/FontName' dictionary entry! */ root->family_name = info->family_name; root->style_name = NULL; if ( root->family_name ) { char* full = info->full_name; char* family = root->family_name; if ( full ) { FT_Bool the_same = TRUE; while ( *full ) { if ( *full == *family ) { family++; full++; } else { if ( *full == ' ' || *full == '-' ) full++; else if ( *family == ' ' || *family == '-' ) family++; else { the_same = FALSE; if ( !*family ) root->style_name = full; break; } } } if ( the_same ) root->style_name = (char *)"Regular"; } } else { /* do we have a `/FontName'? */ if ( type1->font_name ) root->family_name = type1->font_name; } if ( !root->style_name ) { if ( info->weight ) root->style_name = info->weight; else /* assume `Regular' style because we don't know better */ root->style_name = (char *)"Regular"; } /* compute style flags */ root->style_flags = 0; if ( info->italic_angle ) root->style_flags |= FT_STYLE_FLAG_ITALIC; if ( info->weight ) { if ( !ft_strcmp( info->weight, "Bold" ) || !ft_strcmp( info->weight, "Black" ) ) root->style_flags |= FT_STYLE_FLAG_BOLD; } /* no embedded bitmap support */ root->num_fixed_sizes = 0; root->available_sizes = NULL; root->bbox.xMin = type1->font_bbox.xMin >> 16; root->bbox.yMin = type1->font_bbox.yMin >> 16; /* no `U' suffix here to 0xFFFF! */ root->bbox.xMax = ( type1->font_bbox.xMax + 0xFFFF ) >> 16; root->bbox.yMax = ( type1->font_bbox.yMax + 0xFFFF ) >> 16; /* Set units_per_EM if we didn't set it in t1_parse_font_matrix. */ if ( !root->units_per_EM ) root->units_per_EM = 1000; root->ascender = (FT_Short)( root->bbox.yMax ); root->descender = (FT_Short)( root->bbox.yMin ); root->height = (FT_Short)( ( root->units_per_EM * 12 ) / 10 ); if ( root->height < root->ascender - root->descender ) root->height = (FT_Short)( root->ascender - root->descender ); /* now compute the maximum advance width */ root->max_advance_width = (FT_Short)( root->bbox.xMax ); { FT_Pos max_advance; error = T1_Compute_Max_Advance( face, &max_advance ); /* in case of error, keep the standard width */ if ( !error ) root->max_advance_width = (FT_Short)FIXED_TO_INT( max_advance ); else error = FT_Err_Ok; /* clear error */ } root->max_advance_height = root->height; root->underline_position = (FT_Short)info->underline_position; root->underline_thickness = (FT_Short)info->underline_thickness; } { FT_Face root = &face->root; if ( psnames ) { FT_CharMapRec charmap; T1_CMap_Classes cmap_classes = psaux->t1_cmap_classes; FT_CMap_Class clazz; charmap.face = root; /* first of all, try to synthesize a Unicode charmap */ charmap.platform_id = TT_PLATFORM_MICROSOFT; charmap.encoding_id = TT_MS_ID_UNICODE_CS; charmap.encoding = FT_ENCODING_UNICODE; error = FT_CMap_New( cmap_classes->unicode, NULL, &charmap, NULL ); if ( error && FT_ERR_NEQ( error, No_Unicode_Glyph_Name ) ) goto Exit; error = FT_Err_Ok; /* now, generate an Adobe Standard encoding when appropriate */ charmap.platform_id = TT_PLATFORM_ADOBE; clazz = NULL; switch ( type1->encoding_type ) { case T1_ENCODING_TYPE_STANDARD: charmap.encoding = FT_ENCODING_ADOBE_STANDARD; charmap.encoding_id = TT_ADOBE_ID_STANDARD; clazz = cmap_classes->standard; break; case T1_ENCODING_TYPE_EXPERT: charmap.encoding = FT_ENCODING_ADOBE_EXPERT; charmap.encoding_id = TT_ADOBE_ID_EXPERT; clazz = cmap_classes->expert; break; case T1_ENCODING_TYPE_ARRAY: charmap.encoding = FT_ENCODING_ADOBE_CUSTOM; charmap.encoding_id = TT_ADOBE_ID_CUSTOM; clazz = cmap_classes->custom; break; case T1_ENCODING_TYPE_ISOLATIN1: charmap.encoding = FT_ENCODING_ADOBE_LATIN_1; charmap.encoding_id = TT_ADOBE_ID_LATIN_1; clazz = cmap_classes->unicode; break; default: ; } if ( clazz ) error = FT_CMap_New( clazz, NULL, &charmap, NULL ); #if 0 /* Select default charmap */ if (root->num_charmaps) root->charmap = root->charmaps[0]; #endif } } Exit: return error; }
cid_driver_done( FT_Module driver ) { FT_UNUSED( driver ); }
CFF_Driver_Init( CFF_Driver driver ) { FT_UNUSED( driver ); return CFF_Err_Ok; }
cff_driver_init( FT_Module module ) { FT_UNUSED( module ); return CFF_Err_Ok; }
CFF_Driver_Done( CFF_Driver driver ) { FT_UNUSED( driver ); }
sfnt_load_face( FT_Stream stream, TT_Face face, FT_Int face_index, FT_Int num_params, FT_Parameter* params ) { FT_Error error; #ifdef TT_CONFIG_OPTION_POSTSCRIPT_NAMES FT_Error psnames_error; #endif FT_Bool has_outline; FT_Bool is_apple_sbit; FT_Bool ignore_preferred_family = FALSE; FT_Bool ignore_preferred_subfamily = FALSE; SFNT_Service sfnt = (SFNT_Service)face->sfnt; FT_UNUSED( face_index ); /* Check parameters */ { FT_Int i; for ( i = 0; i < num_params; i++ ) { if ( params[i].tag == FT_PARAM_TAG_IGNORE_PREFERRED_FAMILY ) ignore_preferred_family = TRUE; else if ( params[i].tag == FT_PARAM_TAG_IGNORE_PREFERRED_SUBFAMILY ) ignore_preferred_subfamily = TRUE; } } /* Load tables */ /* We now support two SFNT-based bitmapped font formats. They */ /* are recognized easily as they do not include a `glyf' */ /* table. */ /* */ /* The first format comes from Apple, and uses a table named */ /* `bhed' instead of `head' to store the font header (using */ /* the same format). It also doesn't include horizontal and */ /* vertical metrics tables (i.e. `hhea' and `vhea' tables are */ /* missing). */ /* */ /* The other format comes from Microsoft, and is used with */ /* WinCE/PocketPC. It looks like a standard TTF, except that */ /* it doesn't contain outlines. */ /* */ FT_TRACE2(( "sfnt_load_face: %08p\n\n", face )); /* do we have outlines in there? */ #ifdef FT_CONFIG_OPTION_INCREMENTAL has_outline = FT_BOOL( face->root.internal->incremental_interface != 0 || tt_face_lookup_table( face, TTAG_glyf ) != 0 || tt_face_lookup_table( face, TTAG_CFF ) != 0 ); #else has_outline = FT_BOOL( tt_face_lookup_table( face, TTAG_glyf ) != 0 || tt_face_lookup_table( face, TTAG_CFF ) != 0 ); #endif is_apple_sbit = 0; /* if this font doesn't contain outlines, we try to load */ /* a `bhed' table */ if ( !has_outline && sfnt->load_bhed ) { LOAD_( bhed ); is_apple_sbit = FT_BOOL( !error ); } /* load the font header (`head' table) if this isn't an Apple */ /* sbit font file */ if ( !is_apple_sbit ) { LOAD_( head ); if ( error ) goto Exit; } if ( face->header.Units_Per_EM == 0 ) { error = FT_THROW( Invalid_Table ); goto Exit; } /* the following tables are often not present in embedded TrueType */ /* fonts within PDF documents, so don't check for them. */ LOAD_( maxp ); LOAD_( cmap ); /* the following tables are optional in PCL fonts -- */ /* don't check for errors */ LOAD_( name ); LOAD_( post ); #ifdef TT_CONFIG_OPTION_POSTSCRIPT_NAMES psnames_error = error; #endif /* do not load the metrics headers and tables if this is an Apple */ /* sbit font file */ if ( !is_apple_sbit ) { /* load the `hhea' and `hmtx' tables */ LOADM_( hhea, 0 ); if ( !error ) { LOADM_( hmtx, 0 ); if ( FT_ERR_EQ( error, Table_Missing ) ) { error = FT_THROW( Hmtx_Table_Missing ); #ifdef FT_CONFIG_OPTION_INCREMENTAL /* If this is an incrementally loaded font and there are */ /* overriding metrics, tolerate a missing `hmtx' table. */ if ( face->root.internal->incremental_interface && face->root.internal->incremental_interface->funcs-> get_glyph_metrics ) { face->horizontal.number_Of_HMetrics = 0; error = FT_Err_Ok; } #endif } } else if ( FT_ERR_EQ( error, Table_Missing ) ) { /* No `hhea' table necessary for SFNT Mac fonts. */ if ( face->format_tag == TTAG_true ) { FT_TRACE2(( "This is an SFNT Mac font.\n" )); has_outline = 0; error = FT_Err_Ok; } else { error = FT_THROW( Horiz_Header_Missing ); #ifdef FT_CONFIG_OPTION_INCREMENTAL /* If this is an incrementally loaded font and there are */ /* overriding metrics, tolerate a missing `hhea' table. */ if ( face->root.internal->incremental_interface && face->root.internal->incremental_interface->funcs-> get_glyph_metrics ) { face->horizontal.number_Of_HMetrics = 0; error = FT_Err_Ok; } #endif } } if ( error ) goto Exit; /* try to load the `vhea' and `vmtx' tables */ LOADM_( hhea, 1 ); if ( !error ) { LOADM_( hmtx, 1 ); if ( !error ) face->vertical_info = 1; } if ( error && FT_ERR_NEQ( error, Table_Missing ) ) goto Exit; LOAD_( os2 ); if ( error ) { /* we treat the table as missing if there are any errors */ face->os2.version = 0xFFFFU; } } /* the optional tables */ /* embedded bitmap support */ if ( sfnt->load_eblc ) { LOAD_( eblc ); if ( error ) { /* a font which contains neither bitmaps nor outlines is */ /* still valid (although rather useless in most cases); */ /* however, you can find such stripped fonts in PDFs */ if ( FT_ERR_EQ( error, Table_Missing ) ) error = FT_Err_Ok; else goto Exit; } } LOAD_( pclt ); if ( error ) { if ( FT_ERR_NEQ( error, Table_Missing ) ) goto Exit; face->pclt.Version = 0; } /* consider the kerning and gasp tables as optional */ LOAD_( gasp ); LOAD_( kern ); face->root.num_glyphs = face->max_profile.numGlyphs; /* FreeType don't have generalized method which distinguish Arial Black from Arial. */ /* In our QtWebKit for Windows FreeType edition, the problem cause using Arial Black font */ /* when a content have "font-family: Arial". */ /* The Arial problem due to Arial and Arial Black return "Arial" as preferred family. */ /* We read font family, not preferred family, for the workaround. */ /* The newer freetype have ignore preferred option. */ /* The optiom may fix this bug, but you should consider WWS family. */ GET_NAME( FONT_FAMILY, &face->root.family_name ); GET_NAME( FONT_SUBFAMILY, &face->root.style_name ); /* now set up root fields */ { FT_Face root = &face->root; FT_Long flags = root->face_flags; /*********************************************************************/ /* */ /* Compute face flags. */ /* */ if ( has_outline == TRUE ) flags |= FT_FACE_FLAG_SCALABLE; /* scalable outlines */ /* The sfnt driver only supports bitmap fonts natively, thus we */ /* don't set FT_FACE_FLAG_HINTER. */ flags |= FT_FACE_FLAG_SFNT | /* SFNT file format */ FT_FACE_FLAG_HORIZONTAL; /* horizontal data */ #ifdef TT_CONFIG_OPTION_POSTSCRIPT_NAMES if ( !psnames_error && face->postscript.FormatType != 0x00030000L ) flags |= FT_FACE_FLAG_GLYPH_NAMES; #endif /* fixed width font? */ if ( face->postscript.isFixedPitch ) flags |= FT_FACE_FLAG_FIXED_WIDTH; /* vertical information? */ if ( face->vertical_info ) flags |= FT_FACE_FLAG_VERTICAL; /* kerning available ? */ if ( TT_FACE_HAS_KERNING( face ) ) flags |= FT_FACE_FLAG_KERNING; #ifdef TT_CONFIG_OPTION_GX_VAR_SUPPORT /* Don't bother to load the tables unless somebody asks for them. */ /* No need to do work which will (probably) not be used. */ if ( tt_face_lookup_table( face, TTAG_glyf ) != 0 && tt_face_lookup_table( face, TTAG_fvar ) != 0 && tt_face_lookup_table( face, TTAG_gvar ) != 0 ) flags |= FT_FACE_FLAG_MULTIPLE_MASTERS; #endif root->face_flags = flags; /*********************************************************************/ /* */ /* Compute style flags. */ /* */ flags = 0; if ( has_outline == TRUE && face->os2.version != 0xFFFFU ) { /* We have an OS/2 table; use the `fsSelection' field. Bit 9 */ /* indicates an oblique font face. This flag has been */ /* introduced in version 1.5 of the OpenType specification. */ if ( face->os2.fsSelection & 512 ) /* bit 9 */ flags |= FT_STYLE_FLAG_ITALIC; else if ( face->os2.fsSelection & 1 ) /* bit 0 */ flags |= FT_STYLE_FLAG_ITALIC; if ( face->os2.fsSelection & 32 ) /* bit 5 */ flags |= FT_STYLE_FLAG_BOLD; } else { /* this is an old Mac font, use the header field */ if ( face->header.Mac_Style & 1 ) flags |= FT_STYLE_FLAG_BOLD; if ( face->header.Mac_Style & 2 ) flags |= FT_STYLE_FLAG_ITALIC; } root->style_flags = flags; /*********************************************************************/ /* */ /* Polish the charmaps. */ /* */ /* Try to set the charmap encoding according to the platform & */ /* encoding ID of each charmap. */ /* */ tt_face_build_cmaps( face ); /* ignore errors */ /* set the encoding fields */ { FT_Int m; for ( m = 0; m < root->num_charmaps; m++ ) { FT_CharMap charmap = root->charmaps[m]; charmap->encoding = sfnt_find_encoding( charmap->platform_id, charmap->encoding_id ); #if 0 if ( root->charmap == NULL && charmap->encoding == FT_ENCODING_UNICODE ) { /* set 'root->charmap' to the first Unicode encoding we find */ root->charmap = charmap; } #endif } } #ifdef TT_CONFIG_OPTION_EMBEDDED_BITMAPS /* * Now allocate the root array of FT_Bitmap_Size records and * populate them. Unfortunately, it isn't possible to indicate bit * depths in the FT_Bitmap_Size record. This is a design error. */ { FT_UInt i, count; count = face->sbit_num_strikes; if ( count > 0 ) { FT_Memory memory = face->root.stream->memory; FT_UShort em_size = face->header.Units_Per_EM; FT_Short avgwidth = face->os2.xAvgCharWidth; FT_Size_Metrics metrics; if ( em_size == 0 || face->os2.version == 0xFFFFU ) { avgwidth = 0; em_size = 1; } if ( FT_NEW_ARRAY( root->available_sizes, count ) ) goto Exit; for ( i = 0; i < count; i++ ) { FT_Bitmap_Size* bsize = root->available_sizes + i; error = sfnt->load_strike_metrics( face, i, &metrics ); if ( error ) goto Exit; bsize->height = (FT_Short)( metrics.height >> 6 ); bsize->width = (FT_Short)( ( avgwidth * metrics.x_ppem + em_size / 2 ) / em_size ); bsize->x_ppem = metrics.x_ppem << 6; bsize->y_ppem = metrics.y_ppem << 6; /* assume 72dpi */ bsize->size = metrics.y_ppem << 6; } root->face_flags |= FT_FACE_FLAG_FIXED_SIZES; root->num_fixed_sizes = (FT_Int)count; } } #endif /* TT_CONFIG_OPTION_EMBEDDED_BITMAPS */ /* a font with no bitmaps and no outlines is scalable; */ /* it has only empty glyphs then */ if ( !FT_HAS_FIXED_SIZES( root ) && !FT_IS_SCALABLE( root ) ) root->face_flags |= FT_FACE_FLAG_SCALABLE; /*********************************************************************/ /* */ /* Set up metrics. */ /* */ if ( FT_IS_SCALABLE( root ) ) { /* XXX What about if outline header is missing */ /* (e.g. sfnt wrapped bitmap)? */ root->bbox.xMin = face->header.xMin; root->bbox.yMin = face->header.yMin; root->bbox.xMax = face->header.xMax; root->bbox.yMax = face->header.yMax; root->units_per_EM = face->header.Units_Per_EM; /* XXX: Computing the ascender/descender/height is very different */ /* from what the specification tells you. Apparently, we */ /* must be careful because */ /* */ /* - not all fonts have an OS/2 table; in this case, we take */ /* the values in the horizontal header. However, these */ /* values very often are not reliable. */ /* */ /* - otherwise, the correct typographic values are in the */ /* sTypoAscender, sTypoDescender & sTypoLineGap fields. */ /* */ /* However, certain fonts have these fields set to 0. */ /* Rather, they have usWinAscent & usWinDescent correctly */ /* set (but with different values). */ /* */ /* As an example, Arial Narrow is implemented through four */ /* files ARIALN.TTF, ARIALNI.TTF, ARIALNB.TTF & ARIALNBI.TTF */ /* */ /* Strangely, all fonts have the same values in their */ /* sTypoXXX fields, except ARIALNB which sets them to 0. */ /* */ /* On the other hand, they all have different */ /* usWinAscent/Descent values -- as a conclusion, the OS/2 */ /* table cannot be used to compute the text height reliably! */ /* */ /* The ascender and descender are taken from the `hhea' table. */ /* If zero, they are taken from the `OS/2' table. */ root->ascender = face->horizontal.Ascender; root->descender = face->horizontal.Descender; root->height = (FT_Short)( root->ascender - root->descender + face->horizontal.Line_Gap ); if ( !( root->ascender || root->descender ) ) { if ( face->os2.version != 0xFFFFU ) { if ( face->os2.sTypoAscender || face->os2.sTypoDescender ) { root->ascender = face->os2.sTypoAscender; root->descender = face->os2.sTypoDescender; root->height = (FT_Short)( root->ascender - root->descender + face->os2.sTypoLineGap ); } else { root->ascender = (FT_Short)face->os2.usWinAscent; root->descender = -(FT_Short)face->os2.usWinDescent; root->height = (FT_UShort)( root->ascender - root->descender ); } } } root->max_advance_width = face->horizontal.advance_Width_Max; root->max_advance_height = (FT_Short)( face->vertical_info ? face->vertical.advance_Height_Max : root->height ); /* See http://www.microsoft.com/OpenType/OTSpec/post.htm -- */ /* Adjust underline position from top edge to centre of */ /* stroke to convert TrueType meaning to FreeType meaning. */ root->underline_position = face->postscript.underlinePosition - face->postscript.underlineThickness / 2; root->underline_thickness = face->postscript.underlineThickness; } }
cff_driver_done( FT_Module module ) /* CFF_Driver */ { FT_UNUSED( module ); }
T1_Driver_Init( T1_Driver driver ) { FT_UNUSED( driver ); return T1_Err_Ok; }
tt_face_get_kerning( TT_Face face, FT_UInt left_glyph, FT_UInt right_glyph ) { FT_Int result = 0; FT_UInt count, mask = 1; FT_Byte* p = face->kern_table; FT_Byte* p_limit = p + face->kern_table_size; p += 4; mask = 0x0001; for ( count = face->num_kern_tables; count > 0 && p + 6 <= p_limit; count--, mask <<= 1 ) { FT_Byte* base = p; FT_Byte* next = base; FT_UInt version = FT_NEXT_USHORT( p ); FT_UInt length = FT_NEXT_USHORT( p ); FT_UInt coverage = FT_NEXT_USHORT( p ); FT_UInt num_pairs; FT_Int value = 0; FT_UNUSED( version ); next = base + length; if ( next > p_limit ) /* handle broken table */ next = p_limit; if ( ( face->kern_avail_bits & mask ) == 0 ) goto NextTable; if ( p + 8 > next ) goto NextTable; num_pairs = FT_NEXT_USHORT( p ); p += 6; if ( ( next - p ) / 6 < ( int )num_pairs ) /* handle broken count */ num_pairs = ( FT_UInt )( ( next - p ) / 6 ); switch ( coverage >> 8 ) { case 0: { FT_ULong key0 = TT_KERN_INDEX( left_glyph, right_glyph ); if ( face->kern_order_bits & mask ) /* binary search */ { FT_UInt min = 0; FT_UInt max = num_pairs; while ( min < max ) { FT_UInt mid = ( min + max ) >> 1; FT_Byte* q = p + 6 * mid; FT_ULong key; key = FT_NEXT_ULONG( q ); if ( key == key0 ) { value = FT_PEEK_SHORT( q ); goto Found; } if ( key < key0 ) min = mid + 1; else max = mid; } } else /* linear search */ { FT_UInt count2; for ( count2 = num_pairs; count2 > 0; count2-- ) { FT_ULong key = FT_NEXT_ULONG( p ); if ( key == key0 ) { value = FT_PEEK_SHORT( p ); goto Found; } p += 2; } } } break; /* * We don't support format 2 because we haven't seen a single font * using it in real life... */ default: ; }
tt_driver_done( FT_Module ttdriver ) /* TT_Driver */ { FT_UNUSED( ttdriver ); }
static const char* sfnt_get_ps_name( TT_Face face ) { FT_Int n, found_win, found_apple; const char* result = NULL; /* shouldn't happen, but just in case to avoid memory leaks */ if ( face->postscript_name ) return face->postscript_name; /* scan the name table to see whether we have a Postscript name here, */ /* either in Macintosh or Windows platform encodings */ found_win = -1; found_apple = -1; for ( n = 0; n < face->num_names; n++ ) { TT_NameEntryRec* name = face->name_table.names + n; if ( name->nameID == 6 && name->stringLength > 0 ) { if ( name->platformID == 3 && name->encodingID == 1 && name->languageID == 0x409 ) found_win = n; if ( name->platformID == 1 && name->encodingID == 0 && name->languageID == 0 ) found_apple = n; } } if ( found_win != -1 ) { FT_Memory memory = face->root.memory; TT_NameEntryRec* name = face->name_table.names + found_win; FT_UInt len = name->stringLength / 2; FT_Error error = FT_Err_Ok; FT_UNUSED( error ); if ( !FT_ALLOC( result, name->stringLength + 1 ) ) { FT_Stream stream = face->name_table.stream; FT_String* r = (FT_String*)result; FT_Char* p; if ( FT_STREAM_SEEK( name->stringOffset ) || FT_FRAME_ENTER( name->stringLength ) ) { FT_FREE( result ); name->stringLength = 0; name->stringOffset = 0; FT_FREE( name->string ); goto Exit; } p = (FT_Char*)stream->cursor; for ( ; len > 0; len--, p += 2 ) { if ( p[0] == 0 && p[1] >= 32 ) *r++ = p[1]; } *r = '\0'; FT_FRAME_EXIT(); } goto Exit; } if ( found_apple != -1 ) { FT_Memory memory = face->root.memory; TT_NameEntryRec* name = face->name_table.names + found_apple; FT_UInt len = name->stringLength; FT_Error error = FT_Err_Ok; FT_UNUSED( error ); if ( !FT_ALLOC( result, len + 1 ) ) { FT_Stream stream = face->name_table.stream; if ( FT_STREAM_SEEK( name->stringOffset ) || FT_STREAM_READ( result, len ) ) { name->stringOffset = 0; name->stringLength = 0; FT_FREE( name->string ); FT_FREE( result ); goto Exit; } ((char*)result)[len] = '\0'; } } Exit: face->postscript_name = result; return result; }
static FT_Error FNT_Load_Glyph( FT_GlyphSlot slot, FT_Size size, FT_UInt glyph_index, FT_Int32 load_flags ) { FNT_Face face = (FNT_Face)FT_SIZE_FACE( size ); FNT_Font font = face->font; FT_Error error = FNT_Err_Ok; FT_Byte* p; FT_Int len; FT_Bitmap* bitmap = &slot->bitmap; FT_ULong offset; FT_Bool new_format; FT_UNUSED( load_flags ); if ( !face || !font ) { error = FNT_Err_Invalid_Argument; goto Exit; } if ( glyph_index > 0 ) glyph_index--; /* revert to real index */ else glyph_index = font->header.default_char; /* the .notdef glyph */ new_format = FT_BOOL( font->header.version == 0x300 ); len = new_format ? 6 : 4; /* jump to glyph entry */ p = font->fnt_frame + ( new_format ? 146 : 118 ) + len * glyph_index; bitmap->width = FT_NEXT_SHORT_LE( p ); if ( new_format ) offset = FT_NEXT_ULONG_LE( p ); else offset = FT_NEXT_USHORT_LE( p ); /* jump to glyph data */ p = font->fnt_frame + /* font->header.bits_offset */ + offset; /* allocate and build bitmap */ { FT_Memory memory = FT_FACE_MEMORY( slot->face ); FT_Int pitch = ( bitmap->width + 7 ) >> 3; FT_Byte* column; FT_Byte* write; bitmap->pitch = pitch; bitmap->rows = font->header.pixel_height; bitmap->pixel_mode = FT_PIXEL_MODE_MONO; /* note: since glyphs are stored in columns and not in rows we */ /* can't use ft_glyphslot_set_bitmap */ if ( FT_ALLOC( bitmap->buffer, pitch * bitmap->rows ) ) goto Exit; column = (FT_Byte*)bitmap->buffer; for ( ; pitch > 0; pitch--, column++ ) { FT_Byte* limit = p + bitmap->rows; for ( write = column; p < limit; p++, write += bitmap->pitch ) *write = *p; } } slot->internal->flags = FT_GLYPH_OWN_BITMAP; slot->bitmap_left = 0; slot->bitmap_top = font->header.ascent; slot->format = FT_GLYPH_FORMAT_BITMAP; /* now set up metrics */ slot->metrics.horiAdvance = bitmap->width << 6; slot->metrics.horiBearingX = 0; slot->metrics.horiBearingY = slot->bitmap_top << 6; slot->linearHoriAdvance = (FT_Fixed)bitmap->width << 16; slot->format = FT_GLYPH_FORMAT_BITMAP; Exit: return error; }
cid_face_init( FT_Stream stream, FT_Face cidface, /* CID_Face */ FT_Int face_index, FT_Int num_params, FT_Parameter* params ) { CID_Face face = (CID_Face)cidface; FT_Error error; PSAux_Service psaux; PSHinter_Service pshinter; FT_UNUSED( num_params ); FT_UNUSED( params ); FT_UNUSED( stream ); cidface->num_faces = 1; psaux = (PSAux_Service)face->psaux; if ( !psaux ) { psaux = (PSAux_Service)FT_Get_Module_Interface( FT_FACE_LIBRARY( face ), "psaux" ); face->psaux = psaux; } pshinter = (PSHinter_Service)face->pshinter; if ( !pshinter ) { pshinter = (PSHinter_Service)FT_Get_Module_Interface( FT_FACE_LIBRARY( face ), "pshinter" ); face->pshinter = pshinter; } /* open the tokenizer; this will also check the font format */ if ( FT_STREAM_SEEK( 0 ) ) goto Exit; error = cid_face_open( face, face_index ); if ( error ) goto Exit; /* if we just wanted to check the format, leave successfully now */ if ( face_index < 0 ) goto Exit; /* check the face index */ if ( face_index != 0 ) { FT_ERROR(( "cid_face_init: invalid face index\n" )); error = CID_Err_Invalid_Argument; goto Exit; } /* now load the font program into the face object */ /* initialize the face object fields */ /* set up root face fields */ { CID_FaceInfo cid = &face->cid; PS_FontInfo info = &cid->font_info; cidface->num_glyphs = cid->cid_count; cidface->num_charmaps = 0; cidface->face_index = face_index; cidface->face_flags = FT_FACE_FLAG_SCALABLE; cidface->face_flags |= FT_FACE_FLAG_HORIZONTAL; if ( info->is_fixed_pitch ) cidface->face_flags |= FT_FACE_FLAG_FIXED_WIDTH; /* XXX: TODO: add kerning with .afm support */ /* get style name -- be careful, some broken fonts only */ /* have a /FontName dictionary entry! */ cidface->family_name = info->family_name; /* assume "Regular" style if we don't know better */ cidface->style_name = (char *)"Regular"; if ( cidface->family_name ) { char* full = info->full_name; char* family = cidface->family_name; if ( full ) { while ( *full ) { if ( *full == *family ) { family++; full++; } else { if ( *full == ' ' || *full == '-' ) full++; else if ( *family == ' ' || *family == '-' ) family++; else { if ( !*family ) cidface->style_name = full; break; } } } } } else { /* do we have a `/FontName'? */ if ( cid->cid_font_name ) cidface->family_name = cid->cid_font_name; } /* compute style flags */ cidface->style_flags = 0; if ( info->italic_angle ) cidface->style_flags |= FT_STYLE_FLAG_ITALIC; if ( info->weight ) { if ( !ft_strcmp( info->weight, "Bold" ) || !ft_strcmp( info->weight, "Black" ) ) cidface->style_flags |= FT_STYLE_FLAG_BOLD; } /* no embedded bitmap support */ cidface->num_fixed_sizes = 0; cidface->available_sizes = 0; cidface->bbox.xMin = cid->font_bbox.xMin >> 16; cidface->bbox.yMin = cid->font_bbox.yMin >> 16; cidface->bbox.xMax = ( cid->font_bbox.xMax + 0xFFFFU ) >> 16; cidface->bbox.yMax = ( cid->font_bbox.yMax + 0xFFFFU ) >> 16; if ( !cidface->units_per_EM ) cidface->units_per_EM = 1000; cidface->ascender = (FT_Short)( cidface->bbox.yMax ); cidface->descender = (FT_Short)( cidface->bbox.yMin ); cidface->height = (FT_Short)( ( ( cidface->ascender - cidface->descender ) * 12 ) / 10 ); cidface->underline_position = (FT_Short)info->underline_position; cidface->underline_thickness = (FT_Short)info->underline_thickness; cidface->internal->max_points = 0; cidface->internal->max_contours = 0; } Exit: return error; }
PCF_Face_Init( FT_Stream stream, PCF_Face face, FT_Int face_index, FT_Int num_params, FT_Parameter* params ) { FT_Error error = PCF_Err_Ok; FT_UNUSED( num_params ); FT_UNUSED( params ); FT_UNUSED( face_index ); error = pcf_load_font( stream, face ); if ( error ) { FT_Error error2; /* this didn't work, try gzip support! */ error2 = FT_Stream_OpenGzip( &face->gzip_stream, stream ); if ( error2 == PCF_Err_Unimplemented_Feature ) goto Fail; error = error2; if ( error ) goto Fail; face->gzip_source = stream; face->root.stream = &face->gzip_stream; stream = face->root.stream; error = pcf_load_font( stream, face ); if ( error ) goto Fail; } /* set-up charmap */ { FT_String *charset_registry, *charset_encoding; FT_Bool unicode_charmap = 0; charset_registry = face->charset_registry; charset_encoding = face->charset_encoding; if ( ( charset_registry != NULL ) && ( charset_encoding != NULL ) ) { char* s = face->charset_registry; /* Uh, oh, compare first letters manually to avoid dependency on locales. */ if ( ( s[0] == 'i' || s[0] == 'I' ) && ( s[1] == 's' || s[1] == 'S' ) && ( s[2] == 'o' || s[2] == 'O' ) ) { s += 3; if ( !ft_strcmp( s, "10646" ) || ( !ft_strcmp( s, "8859" ) && !ft_strcmp( face->charset_encoding, "1" ) ) ) unicode_charmap = 1; } } { FT_CharMapRec charmap; charmap.face = FT_FACE( face ); charmap.encoding = FT_ENCODING_NONE; charmap.platform_id = 0; charmap.encoding_id = 0; if ( unicode_charmap ) { charmap.encoding = FT_ENCODING_UNICODE; charmap.platform_id = 3; charmap.encoding_id = 1; } error = FT_CMap_New( &pcf_cmap_class, NULL, &charmap, NULL ); #if 0 /* Select default charmap */ if (face->root.num_charmaps) face->root.charmap = face->root.charmaps[0]; #endif } } Exit: return error; Fail: FT_TRACE2(( "[not a valid PCF file]\n" )); error = PCF_Err_Unknown_File_Format; /* error */ goto Exit; }
cid_driver_init( FT_Module driver ) { FT_UNUSED( driver ); return CID_Err_Ok; }
t1_decoder_parse_charstrings( T1_Decoder decoder, FT_Byte* charstring_base, FT_UInt charstring_len ) { FT_Error error; T1_Decoder_Zone zone; FT_Byte* ip; FT_Byte* limit; T1_Builder builder = &decoder->builder; FT_Pos x, y, orig_x, orig_y; T1_Hints_Funcs hinter; /* we don't want to touch the source code -- use macro trick */ #define start_point t1_builder_start_point #define check_points t1_builder_check_points #define add_point t1_builder_add_point #define add_point1 t1_builder_add_point1 #define add_contour t1_builder_add_contour #define close_contour t1_builder_close_contour /* First of all, initialize the decoder */ decoder->top = decoder->stack; decoder->zone = decoder->zones; zone = decoder->zones; builder->parse_state = T1_Parse_Start; hinter = (T1_Hints_Funcs)builder->hints_funcs; zone->base = charstring_base; limit = zone->limit = charstring_base + charstring_len; ip = zone->cursor = zone->base; error = PSaux_Err_Ok; x = orig_x = builder->pos_x; y = orig_y = builder->pos_y; /* begin hints recording session, if any */ if ( hinter ) hinter->open( hinter->hints ); /* now, execute loop */ while ( ip < limit ) { FT_Long* top = decoder->top; T1_Operator op = op_none; FT_Long value = 0; /*********************************************************************/ /* */ /* Decode operator or operand */ /* */ /* */ /* first of all, decompress operator or value */ switch ( *ip++ ) { case 1: op = op_hstem; break; case 3: op = op_vstem; break; case 4: op = op_vmoveto; break; case 5: op = op_rlineto; break; case 6: op = op_hlineto; break; case 7: op = op_vlineto; break; case 8: op = op_rrcurveto; break; case 9: op = op_closepath; break; case 10: op = op_callsubr; break; case 11: op = op_return; break; case 13: op = op_hsbw; break; case 14: op = op_endchar; break; case 15: /* undocumented, obsolete operator */ op = op_none; break; case 21: op = op_rmoveto; break; case 22: op = op_hmoveto; break; case 30: op = op_vhcurveto; break; case 31: op = op_hvcurveto; break; case 12: if ( ip > limit ) { FT_ERROR(( "t1_decoder_parse_charstrings: " "invalid escape (12+EOF)\n" )); goto Syntax_Error; } switch ( *ip++ ) { case 0: op = op_dotsection; break; case 1: op = op_vstem3; break; case 2: op = op_hstem3; break; case 6: op = op_seac; break; case 7: op = op_sbw; break; case 12: op = op_div; break; case 16: op = op_callothersubr; break; case 17: op = op_pop; break; case 33: op = op_setcurrentpoint; break; default: FT_ERROR(( "t1_decoder_parse_charstrings: " "invalid escape (12+%d)\n", ip[-1] )); goto Syntax_Error; } break; case 255: /* four bytes integer */ if ( ip + 4 > limit ) { FT_ERROR(( "t1_decoder_parse_charstrings: " "unexpected EOF in integer\n" )); goto Syntax_Error; } value = (FT_Int32)( ((FT_Long)ip[0] << 24) | ((FT_Long)ip[1] << 16) | ((FT_Long)ip[2] << 8 ) | ip[3] ); ip += 4; break; default: if ( ip[-1] >= 32 ) { if ( ip[-1] < 247 ) value = (FT_Long)ip[-1] - 139; else { if ( ++ip > limit ) { FT_ERROR(( "t1_decoder_parse_charstrings: " )); FT_ERROR(( "unexpected EOF in integer\n" )); goto Syntax_Error; } if ( ip[-2] < 251 ) value = ( ( (FT_Long)ip[-2] - 247 ) << 8 ) + ip[-1] + 108; else value = -( ( ( (FT_Long)ip[-2] - 251 ) << 8 ) + ip[-1] + 108 ); } } else { FT_ERROR(( "t1_decoder_parse_charstrings: " "invalid byte (%d)\n", ip[-1] )); goto Syntax_Error; } } /*********************************************************************/ /* */ /* Push value on stack, or process operator */ /* */ /* */ if ( op == op_none ) { if ( top - decoder->stack >= T1_MAX_CHARSTRINGS_OPERANDS ) { FT_ERROR(( "t1_decoder_parse_charstrings: stack overflow!\n" )); goto Syntax_Error; } FT_TRACE4(( " %ld", value )); *top++ = value; decoder->top = top; } else if ( op == op_callothersubr ) /* callothersubr */ { FT_TRACE4(( " callothersubr" )); if ( top - decoder->stack < 2 ) goto Stack_Underflow; top -= 2; switch ( (FT_Int)top[1] ) { case 1: /* start flex feature */ if ( top[0] != 0 ) goto Unexpected_OtherSubr; decoder->flex_state = 1; decoder->num_flex_vectors = 0; if ( start_point( builder, x, y ) || check_points( builder, 6 ) ) goto Fail; break; case 2: /* add flex vectors */ { FT_Int idx; if ( top[0] != 0 ) goto Unexpected_OtherSubr; /* note that we should not add a point for index 0; */ /* this will move our current position to the flex */ /* point without adding any point to the outline */ idx = decoder->num_flex_vectors++; if ( idx > 0 && idx < 7 ) add_point( builder, x, y, (FT_Byte)( idx == 3 || idx == 6 ) ); } break; case 0: /* end flex feature */ if ( top[0] != 3 ) goto Unexpected_OtherSubr; if ( decoder->flex_state == 0 || decoder->num_flex_vectors != 7 ) { FT_ERROR(( "t1_decoder_parse_charstrings: " "unexpected flex end\n" )); goto Syntax_Error; } /* now consume the remaining `pop pop setcurpoint' */ if ( ip + 6 > limit || ip[0] != 12 || ip[1] != 17 || /* pop */ ip[2] != 12 || ip[3] != 17 || /* pop */ ip[4] != 12 || ip[5] != 33 ) /* setcurpoint */ { FT_ERROR(( "t1_decoder_parse_charstrings: " "invalid flex charstring\n" )); goto Syntax_Error; } ip += 6; decoder->flex_state = 0; break; case 3: /* change hints */ if ( top[0] != 1 ) goto Unexpected_OtherSubr; /* eat the following `pop' */ if ( ip + 2 > limit ) { FT_ERROR(( "t1_decoder_parse_charstrings: " "invalid escape (12+%d)\n", ip[-1] )); goto Syntax_Error; } if ( ip[0] != 12 || ip[1] != 17 ) { FT_ERROR(( "t1_decoder_parse_charstrings: " )); FT_ERROR(( "`pop' expected, found (%d %d)\n", ip[0], ip[1] )); goto Syntax_Error; } ip += 2; if ( hinter ) hinter->reset( hinter->hints, builder->current->n_points ); break; case 12: case 13: /* counter control hints, clear stack */ top = decoder->stack; break; case 14: case 15: case 16: case 17: case 18: /* multiple masters */ { PS_Blend blend = decoder->blend; FT_UInt num_points, nn, mm; FT_Long* delta; FT_Long* values; if ( !blend ) { FT_ERROR(( "t1_decoder_parse_charstrings: " )); FT_ERROR(( "unexpected multiple masters operator!\n" )); goto Syntax_Error; } num_points = (FT_UInt)top[1] - 13 + ( top[1] == 18 ); if ( top[0] != (FT_Int)( num_points * blend->num_designs ) ) { FT_ERROR(( "t1_decoder_parse_charstrings: " )); FT_ERROR(( "incorrect number of mm arguments\n" )); goto Syntax_Error; } top -= blend->num_designs * num_points; if ( top < decoder->stack ) goto Stack_Underflow; /* we want to compute: */ /* */ /* a0*w0 + a1*w1 + ... + ak*wk */ /* */ /* but we only have the a0, a1-a0, a2-a0, .. ak-a0 */ /* however, given that w0 + w1 + ... + wk == 1, we can */ /* rewrite it easily as: */ /* */ /* a0 + (a1-a0)*w1 + (a2-a0)*w2 + .. + (ak-a0)*wk */ /* */ /* where k == num_designs-1 */ /* */ /* I guess that's why it's written in this `compact' */ /* form. */ /* */ delta = top + num_points; values = top; for ( nn = 0; nn < num_points; nn++ ) { FT_Long tmp = values[0]; for ( mm = 1; mm < blend->num_designs; mm++ ) tmp += FT_MulFix( *delta++, blend->weight_vector[mm] ); *values++ = tmp; } /* note that `top' will be incremented later by calls to `pop' */ break; } default: Unexpected_OtherSubr: FT_ERROR(( "t1_decoder_parse_charstrings: " "invalid othersubr [%d %d]!\n", top[0], top[1] )); goto Syntax_Error; } decoder->top = top; } else /* general operator */ { FT_Int num_args = t1_args_count[op]; if ( top - decoder->stack < num_args ) goto Stack_Underflow; top -= num_args; switch ( op ) { case op_endchar: FT_TRACE4(( " endchar" )); close_contour( builder ); /* close hints recording session */ if ( hinter ) { if (hinter->close( hinter->hints, builder->current->n_points )) goto Syntax_Error; /* apply hints to the loaded glyph outline now */ hinter->apply( hinter->hints, builder->current, (PSH_Globals) builder->hints_globals, decoder->hint_mode ); } /* add current outline to the glyph slot */ FT_GlyphLoader_Add( builder->loader ); /* return now! */ FT_TRACE4(( "\n\n" )); return PSaux_Err_Ok; case op_hsbw: FT_TRACE4(( " hsbw" )); builder->parse_state = T1_Parse_Have_Width; builder->left_bearing.x += top[0]; builder->advance.x = top[1]; builder->advance.y = 0; orig_x = builder->last.x = x = builder->pos_x + top[0]; orig_y = builder->last.y = y = builder->pos_y; FT_UNUSED( orig_y ); /* the `metrics_only' indicates that we only want to compute */ /* the glyph's metrics (lsb + advance width), not load the */ /* rest of it; so exit immediately */ if ( builder->metrics_only ) return PSaux_Err_Ok; break; case op_seac: /* return immediately after the processing */ return t1operator_seac( decoder, top[0], top[1], top[2], (FT_Int)top[3], (FT_Int)top[4] ); case op_sbw: FT_TRACE4(( " sbw" )); builder->parse_state = T1_Parse_Have_Width; builder->left_bearing.x += top[0]; builder->left_bearing.y += top[1]; builder->advance.x = top[2]; builder->advance.y = top[3]; builder->last.x = x = builder->pos_x + top[0]; builder->last.y = y = builder->pos_y + top[1]; /* the `metrics_only' indicates that we only want to compute */ /* the glyph's metrics (lsb + advance width), not load the */ /* rest of it; so exit immediately */ if ( builder->metrics_only ) return PSaux_Err_Ok; break; case op_closepath: FT_TRACE4(( " closepath" )); close_contour( builder ); if ( builder->parse_state != T1_Parse_Have_Path ) goto Syntax_Error; builder->parse_state = T1_Parse_Have_Width; break; case op_hlineto: FT_TRACE4(( " hlineto" )); if ( start_point( builder, x, y ) ) goto Fail; x += top[0]; goto Add_Line; case op_hmoveto: FT_TRACE4(( " hmoveto" )); x += top[0]; if ( !decoder->flex_state ) { if ( builder->parse_state == T1_Parse_Start ) goto Syntax_Error; builder->parse_state = T1_Parse_Have_Moveto; } break; case op_hvcurveto: FT_TRACE4(( " hvcurveto" )); if ( start_point( builder, x, y ) || check_points( builder, 3 ) ) goto Fail; x += top[0]; add_point( builder, x, y, 0 ); x += top[1]; y += top[2]; add_point( builder, x, y, 0 ); y += top[3]; add_point( builder, x, y, 1 ); break; case op_rlineto: FT_TRACE4(( " rlineto" )); if ( start_point( builder, x, y ) ) goto Fail; x += top[0]; y += top[1]; Add_Line: if ( add_point1( builder, x, y ) ) goto Fail; break; case op_rmoveto: FT_TRACE4(( " rmoveto" )); x += top[0]; y += top[1]; if ( !decoder->flex_state ) { if ( builder->parse_state == T1_Parse_Start ) goto Syntax_Error; builder->parse_state = T1_Parse_Have_Moveto; } break; case op_rrcurveto: FT_TRACE4(( " rcurveto" )); if ( start_point( builder, x, y ) || check_points( builder, 3 ) ) goto Fail; x += top[0]; y += top[1]; add_point( builder, x, y, 0 ); x += top[2]; y += top[3]; add_point( builder, x, y, 0 ); x += top[4]; y += top[5]; add_point( builder, x, y, 1 ); break; case op_vhcurveto: FT_TRACE4(( " vhcurveto" )); if ( start_point( builder, x, y ) || check_points( builder, 3 ) ) goto Fail; y += top[0]; add_point( builder, x, y, 0 ); x += top[1]; y += top[2]; add_point( builder, x, y, 0 ); x += top[3]; add_point( builder, x, y, 1 ); break; case op_vlineto: FT_TRACE4(( " vlineto" )); if ( start_point( builder, x, y ) ) goto Fail; y += top[0]; goto Add_Line; case op_vmoveto: FT_TRACE4(( " vmoveto" )); y += top[0]; if ( !decoder->flex_state ) { if ( builder->parse_state == T1_Parse_Start ) goto Syntax_Error; builder->parse_state = T1_Parse_Have_Moveto; } break; case op_div: FT_TRACE4(( " div" )); if ( top[1] ) { *top = top[0] / top[1]; ++top; } else { FT_ERROR(( "t1_decoder_parse_charstrings: division by 0\n" )); goto Syntax_Error; } break; case op_callsubr: { FT_Int idx; FT_TRACE4(( " callsubr" )); idx = (FT_Int)top[0]; if ( idx < 0 || idx >= (FT_Int)decoder->num_subrs ) { FT_ERROR(( "t1_decoder_parse_charstrings: " "invalid subrs index\n" )); goto Syntax_Error; } if ( zone - decoder->zones >= T1_MAX_SUBRS_CALLS ) { FT_ERROR(( "t1_decoder_parse_charstrings: " "too many nested subrs\n" )); goto Syntax_Error; } zone->cursor = ip; /* save current instruction pointer */ zone++; /* The Type 1 driver stores subroutines without the seed bytes. */ /* The CID driver stores subroutines with seed bytes. This */ /* case is taken care of when decoder->subrs_len == 0. */ zone->base = decoder->subrs[idx]; if ( decoder->subrs_len ) zone->limit = zone->base + decoder->subrs_len[idx]; else { /* We are using subroutines from a CID font. We must adjust */ /* for the seed bytes. */ zone->base += ( decoder->lenIV >= 0 ? decoder->lenIV : 0 ); zone->limit = decoder->subrs[idx + 1]; } zone->cursor = zone->base; if ( !zone->base ) { FT_ERROR(( "t1_decoder_parse_charstrings: " "invoking empty subrs!\n" )); goto Syntax_Error; } decoder->zone = zone; ip = zone->base; limit = zone->limit; break; } case op_pop: FT_TRACE4(( " pop" )); /* theoretically, the arguments are already on the stack */ top++; break; case op_return: FT_TRACE4(( " return" )); if ( zone <= decoder->zones ) { FT_ERROR(( "t1_decoder_parse_charstrings: unexpected return\n" )); goto Syntax_Error; } zone--; ip = zone->cursor; limit = zone->limit; decoder->zone = zone; break; case op_dotsection: FT_TRACE4(( " dotsection" )); break; case op_hstem: FT_TRACE4(( " hstem" )); /* record horizontal hint */ if ( hinter ) { /* top[0] += builder->left_bearing.y; */ hinter->stem( hinter->hints, 1, top ); } break; case op_hstem3: FT_TRACE4(( " hstem3" )); /* record horizontal counter-controlled hints */ if ( hinter ) hinter->stem3( hinter->hints, 1, top ); break; case op_vstem: FT_TRACE4(( " vstem" )); /* record vertical hint */ if ( hinter ) { top[0] += orig_x; hinter->stem( hinter->hints, 0, top ); } break; case op_vstem3: FT_TRACE4(( " vstem3" )); /* record vertical counter-controlled hints */ if ( hinter ) { FT_Pos dx = orig_x; top[0] += dx; top[2] += dx; top[4] += dx; hinter->stem3( hinter->hints, 0, top ); } break; case op_setcurrentpoint: FT_TRACE4(( " setcurrentpoint" )); FT_ERROR(( "t1_decoder_parse_charstrings: " )); FT_ERROR(( "unexpected `setcurrentpoint'\n" )); goto Syntax_Error; default: FT_ERROR(( "t1_decoder_parse_charstrings: " "unhandled opcode %d\n", op )); goto Syntax_Error; } decoder->top = top; } /* general operator processing */ } /* while ip < limit */ FT_TRACE4(( "..end..\n\n" )); Fail: return error; Syntax_Error: return PSaux_Err_Syntax_Error; Stack_Underflow: return PSaux_Err_Stack_Underflow; }
T42_Driver_Done( FT_Module module ) { FT_UNUSED( module ); }