📄 ttgload.c
字号:
{ FT_Vector* pp1; FT_Vector* pp2; FT_Vector* pp3; FT_Vector* pp4; /* pp1 = xMin - lsb */ pp1 = outline->points + n_points; pp1->x = load->bbox.xMin - load->left_bearing; pp1->y = 0; /* pp2 = pp1 + aw */ pp2 = pp1 + 1; pp2->x = pp1->x + load->advance; pp2->y = 0; /* pp3 = top side bearing */ pp3 = pp1 + 2; pp3->x = 0; pp3->y = load->top_bearing + load->bbox.yMax; /* pp4 = pp3 - ah */ pp4 = pp1 + 3; pp4->x = 0; pp4->y = pp3->y - load->vadvance; outline->tags[n_points ] = 0; outline->tags[n_points + 1] = 0; outline->tags[n_points + 2] = 0; outline->tags[n_points + 3] = 0; } /* Note that we return four more points that are not */ /* part of the glyph outline. */ n_points += 4;#ifdef TT_CONFIG_OPTION_GX_VAR_SUPPORT if ( ((TT_Face)load->face)->doblend ) { /* Deltas apply to the unscaled data. */ FT_Vector* deltas; FT_Memory memory = load->face->memory; FT_StreamRec saved_stream = *(load->stream); FT_UInt i; /* TT_Vary_Get_Glyph_Deltas uses a frame, thus we have to save */ /* (and restore) the current one */ load->stream->cursor = 0; load->stream->limit = 0; error = TT_Vary_Get_Glyph_Deltas( (TT_Face)(load->face), load->glyph_index, &deltas, n_points ); *(load->stream) = saved_stream; if ( error ) goto Exit; for ( i = 0; i < n_points; ++i ) { outline->points[i].x += deltas[i].x; outline->points[i].y += deltas[i].y; } FT_FREE( deltas ); }#endif /* TT_CONFIG_OPTION_GX_VAR_SUPPORT */ /* set up zone for hinting */ tt_prepare_zone( zone, &gloader->current, 0, 0 ); /* eventually scale the glyph */ if ( !( load->load_flags & FT_LOAD_NO_SCALE ) ) { FT_Vector* vec = zone->cur; FT_Vector* limit = vec + n_points; FT_Fixed x_scale = ((TT_Size)load->size)->metrics.x_scale; FT_Fixed y_scale = ((TT_Size)load->size)->metrics.y_scale; /* first scale the glyph points */ for ( ; vec < limit; vec++ ) { vec->x = FT_MulFix( vec->x, x_scale ); vec->y = FT_MulFix( vec->y, y_scale ); } } cur_to_org( n_points, zone ); /* eventually hint the glyph */ if ( IS_HINTED( load->load_flags ) ) { FT_Pos x = zone->org[n_points-4].x; x = FT_PIX_ROUND( x ) - x; translate_array( n_points, zone->org, x, 0 ); org_to_cur( n_points, zone ); zone->cur[n_points - 3].x = FT_PIX_ROUND( zone->cur[n_points - 3].x ); zone->cur[n_points - 1].y = FT_PIX_ROUND( zone->cur[n_points - 1].y );#ifdef TT_CONFIG_OPTION_BYTECODE_INTERPRETER /* now consider hinting */ if ( n_ins > 0 ) { error = TT_Set_CodeRange( load->exec, tt_coderange_glyph, load->exec->glyphIns, n_ins ); if ( error ) goto Exit; load->exec->is_composite = FALSE; load->exec->pts = *zone; load->exec->pts.n_points += 4; error = TT_Run_Context( load->exec, debug ); if ( error && load->exec->pedantic_hinting ) goto Exit; error = TT_Err_Ok; /* ignore bytecode errors in non-pedantic mode */ }#endif /* TT_CONFIG_OPTION_BYTECODE_INTERPRETER */ } /* save glyph phantom points */ if ( !load->preserve_pps ) { load->pp1 = zone->cur[n_points - 4]; load->pp2 = zone->cur[n_points - 3]; load->pp3 = zone->cur[n_points - 2]; load->pp4 = zone->cur[n_points - 1]; }#if defined( TT_CONFIG_OPTION_BYTECODE_INTERPRETER ) || \ defined( TT_CONFIG_OPTION_GX_VAR_SUPPORT ) Exit:#endif return error; } /*************************************************************************/ /* */ /* <Function> */ /* load_truetype_glyph */ /* */ /* <Description> */ /* Loads a given truetype glyph. Handles composites and uses a */ /* TT_Loader object. */ /* */ static FT_Error load_truetype_glyph( TT_Loader loader, FT_UInt glyph_index, FT_UInt recurse_count ) {#ifdef TT_CONFIG_OPTION_BYTECODE_INTERPRETER FT_Stream stream = loader->stream;#endif FT_Error error; TT_Face face = (TT_Face)loader->face; FT_ULong offset; FT_Int contours_count; FT_UInt num_points, count; FT_Fixed x_scale, y_scale; FT_GlyphLoader gloader = loader->gloader; FT_Bool opened_frame = 0;#ifdef FT_CONFIG_OPTION_INCREMENTAL FT_StreamRec inc_stream; FT_Data glyph_data; FT_Bool glyph_data_loaded = 0;#endif#ifdef TT_CONFIG_OPTION_GX_VAR_SUPPORT FT_Vector *deltas;#endif if ( recurse_count >= TT_MAX_COMPOSITE_RECURSE ) { error = TT_Err_Invalid_Composite; goto Exit; } /* check glyph index */ if ( glyph_index >= (FT_UInt)face->root.num_glyphs ) { error = TT_Err_Invalid_Glyph_Index; goto Exit; } loader->glyph_index = glyph_index; num_points = 0; x_scale = 0x10000L; y_scale = 0x10000L; if ( ( loader->load_flags & FT_LOAD_NO_SCALE ) == 0 ) { x_scale = ((TT_Size)loader->size)->metrics.x_scale; y_scale = ((TT_Size)loader->size)->metrics.y_scale; } /* get metrics, horizontal and vertical */ { FT_Short left_bearing = 0, top_bearing = 0; FT_UShort advance_width = 0, advance_height = 0; Get_HMetrics( face, glyph_index, (FT_Bool)!( loader->load_flags & FT_LOAD_IGNORE_GLOBAL_ADVANCE_WIDTH ), &left_bearing, &advance_width ); Get_VMetrics( face, glyph_index, (FT_Bool)!( loader->load_flags & FT_LOAD_IGNORE_GLOBAL_ADVANCE_WIDTH ), &top_bearing, &advance_height );#ifdef FT_CONFIG_OPTION_INCREMENTAL /* If this is an incrementally loaded font see if there are */ /* overriding metrics for this glyph. */ if ( face->root.internal->incremental_interface && face->root.internal->incremental_interface->funcs->get_glyph_metrics ) { FT_Incremental_MetricsRec metrics; metrics.bearing_x = left_bearing; metrics.bearing_y = 0; metrics.advance = advance_width; error = face->root.internal->incremental_interface->funcs->get_glyph_metrics( face->root.internal->incremental_interface->object, glyph_index, FALSE, &metrics ); if ( error ) goto Exit; left_bearing = (FT_Short)metrics.bearing_x; advance_width = (FT_UShort)metrics.advance; }# if 0 /* GWW: Do I do the same for vertical metrics ??? */ if ( face->root.internal->incremental_interface && face->root.internal->incremental_interface->funcs->get_glyph_metrics ) { FT_Incremental_MetricsRec metrics; metrics.bearing_x = 0; metrics.bearing_y = top_bearing; metrics.advance = advance_height; error = face->root.internal->incremental_interface->funcs->get_glyph_metrics( face->root.internal->incremental_interface->object, glyph_index, TRUE, &metrics ); if ( error ) goto Exit; top_bearing = (FT_Short)metrics.bearing_y; advance_height = (FT_UShort)metrics.advance; }# endif#endif /* FT_CONFIG_OPTION_INCREMENTAL */ loader->left_bearing = left_bearing; loader->advance = advance_width; loader->top_bearing = top_bearing; loader->vadvance = advance_height; if ( !loader->linear_def ) { loader->linear_def = 1; loader->linear = advance_width; } }#ifdef FT_CONFIG_OPTION_INCREMENTAL /* Set `offset' to the start of the glyph program relative to the */ /* start of the 'glyf' table, and `count' to the length of the */ /* glyph program in bytes. */ /* */ /* If we are loading glyph data via the incremental interface, set */ /* the loader stream to a memory stream reading the data returned */ /* by the interface. */ if ( face->root.internal->incremental_interface ) { error = face->root.internal->incremental_interface->funcs->get_glyph_data( face->root.internal->incremental_interface->object, glyph_index, &glyph_data ); if ( error ) goto Exit; glyph_data_loaded = 1; offset = 0; count = glyph_data.length; FT_MEM_ZERO( &inc_stream, sizeof ( inc_stream ) ); FT_Stream_OpenMemory( &inc_stream, glyph_data.pointer, glyph_data.length ); loader->stream = &inc_stream; } else#endif /* FT_CONFIG_OPTION_INCREMENTAL */ offset = tt_face_get_location( face, glyph_index, &count ); if ( count == 0 ) { /* as described by Frederic Loyer, these are spaces, and */ /* not the unknown glyph. */ loader->bbox.xMin = 0; loader->bbox.xMax = 0; loader->bbox.yMin = 0; loader->bbox.yMax = 0; loader->pp1.x = 0; loader->pp2.x = loader->advance; loader->pp3.y = 0; loader->pp4.y = loader->pp3.y-loader->vadvance;#ifdef TT_CONFIG_OPTION_GX_VAR_SUPPORT if ( ((TT_Face)(loader->face))->doblend ) { /* this must be done before scaling */ FT_Memory memory = loader->face->memory; error = TT_Vary_Get_Glyph_Deltas( (TT_Face)(loader->face), glyph_index, &deltas, 4 ); if ( error ) goto Exit; loader->pp1.x += deltas[0].x; loader->pp1.y += deltas[0].y; loader->pp2.x += deltas[1].x; loader->pp2.y += deltas[1].y; loader->pp3.x += deltas[2].x; loader->pp3.y += deltas[2].y; loader->pp4.x += deltas[3].x; loader->pp4.y += deltas[3].y; FT_FREE( deltas ); }#endif if ( ( loader->load_flags & FT_LOAD_NO_SCALE ) == 0 ) { loader->pp2.x = FT_MulFix( loader->pp2.x, x_scale ); loader->pp4.y = FT_MulFix( loader->pp4.y, y_scale ); }#ifdef TT_CONFIG_OPTION_BYTECODE_INTERPRETER if ( loader->exec ) loader->exec->glyphSize = 0;#endif error = TT_Err_Ok; goto Exit; } loader->byte_len = (FT_Int)count; offset = loader->glyf_offset + offset; /* access glyph frame */ error = face->access_glyph_frame( loader, glyph_index, offset, count ); if ( error ) goto Exit; opened_frame = 1; /* read first glyph header */ error = face->read_glyph_header( loader ); if ( error ) goto Fail; contours_count = loader->n_contours; count -= 10; loader->pp1.x = loader->bbox.xMin - loader->left_bearing;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -