📄 ttgload.c
字号:
loader->linear = advance_width; } } /* Set `offset' to the start of the glyph relative to the start of */ /* the `glyf' table, and `byte_len' to the length of the glyph in */ /* bytes. */#ifdef FT_CONFIG_OPTION_INCREMENTAL /* 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; loader->byte_len = 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, (FT_UInt*)&loader->byte_len ); if ( loader->byte_len == 0 ) { /* as described by Frederic Loyer, these are spaces or */ /* the unknown glyph. */ loader->bbox.xMin = 0; loader->bbox.xMax = 0; loader->bbox.yMin = 0; loader->bbox.yMax = 0; TT_LOADER_SET_PP( loader );#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->pp1.x = FT_MulFix( loader->pp1.x, x_scale ); loader->pp2.x = FT_MulFix( loader->pp2.x, x_scale ); loader->pp3.y = FT_MulFix( loader->pp3.y, y_scale ); loader->pp4.y = FT_MulFix( loader->pp4.y, y_scale ); } error = TT_Err_Ok; goto Exit; } error = face->access_glyph_frame( loader, glyph_index, loader->glyf_offset + offset, loader->byte_len ); if ( error ) goto Exit; opened_frame = 1; /* read first glyph header */ error = face->read_glyph_header( loader ); if ( error ) goto Exit; TT_LOADER_SET_PP( loader ); /***********************************************************************/ /***********************************************************************/ /***********************************************************************/ /* if it is a simple glyph, load it */ if ( loader->n_contours >= 0 ) { error = face->read_simple_glyph( loader ); if ( error ) goto Exit; /* all data have been read */ face->forget_glyph_frame( loader ); opened_frame = 0; error = TT_Process_Simple_Glyph( loader ); if ( error ) goto Exit; FT_GlyphLoader_Add( gloader ); } /***********************************************************************/ /***********************************************************************/ /***********************************************************************/ /* otherwise, load a composite! */ else if ( loader->n_contours == -1 ) { FT_UInt start_point; FT_UInt start_contour; FT_ULong ins_pos; /* position of composite instructions, if any */ start_point = gloader->base.outline.n_points; start_contour = gloader->base.outline.n_contours; /* for each subglyph, read composite header */ error = face->read_composite_glyph( loader ); if ( error ) goto Exit; /* store the offset of instructions */ ins_pos = loader->ins_pos; /* all data we need are read */ face->forget_glyph_frame( loader ); opened_frame = 0;#ifdef TT_CONFIG_OPTION_GX_VAR_SUPPORT if ( face->doblend ) { FT_Int i, limit; FT_SubGlyph subglyph; FT_Memory memory = face->root.memory; /* this provides additional offsets */ /* for each component's translation */ if ( (error = TT_Vary_Get_Glyph_Deltas( face, glyph_index, &deltas, gloader->current.num_subglyphs + 4 )) != 0 ) goto Exit; subglyph = gloader->current.subglyphs + gloader->base.num_subglyphs; limit = gloader->current.num_subglyphs; for ( i = 0; i < limit; ++i, ++subglyph ) { if ( subglyph->flags & ARGS_ARE_XY_VALUES ) { subglyph->arg1 += deltas[i].x; subglyph->arg2 += deltas[i].y; } } loader->pp1.x += deltas[i + 0].x; loader->pp1.y += deltas[i + 0].y; loader->pp2.x += deltas[i + 1].x; loader->pp2.y += deltas[i + 1].y; loader->pp3.x += deltas[i + 2].x; loader->pp3.y += deltas[i + 2].y; loader->pp4.x += deltas[i + 3].x; loader->pp4.y += deltas[i + 3].y; FT_FREE( deltas ); }#endif /* TT_CONFIG_OPTION_GX_VAR_SUPPORT */ if ( ( loader->load_flags & FT_LOAD_NO_SCALE ) == 0 ) { loader->pp1.x = FT_MulFix( loader->pp1.x, x_scale ); loader->pp2.x = FT_MulFix( loader->pp2.x, x_scale ); loader->pp3.y = FT_MulFix( loader->pp3.y, y_scale ); loader->pp4.y = FT_MulFix( loader->pp4.y, y_scale ); } /* if the flag FT_LOAD_NO_RECURSE is set, we return the subglyph */ /* `as is' in the glyph slot (the client application will be */ /* responsible for interpreting these data)... */ /* */ if ( loader->load_flags & FT_LOAD_NO_RECURSE ) { FT_GlyphLoader_Add( gloader ); loader->glyph->format = FT_GLYPH_FORMAT_COMPOSITE; goto Exit; } /*********************************************************************/ /*********************************************************************/ /*********************************************************************/ { FT_UInt n, num_base_points; FT_SubGlyph subglyph = 0; FT_UInt num_points = start_point; FT_UInt num_subglyphs = gloader->current.num_subglyphs; FT_UInt num_base_subgs = gloader->base.num_subglyphs; FT_Stream old_stream = loader->stream; FT_GlyphLoader_Add( gloader ); /* read each subglyph independently */ for ( n = 0; n < num_subglyphs; n++ ) { FT_Vector pp[4]; /* Each time we call load_truetype_glyph in this loop, the */ /* value of `gloader.base.subglyphs' can change due to table */ /* reallocations. We thus need to recompute the subglyph */ /* pointer on each iteration. */ subglyph = gloader->base.subglyphs + num_base_subgs + n; pp[0] = loader->pp1; pp[1] = loader->pp2; pp[2] = loader->pp3; pp[3] = loader->pp4; num_base_points = gloader->base.outline.n_points; error = load_truetype_glyph( loader, subglyph->index, recurse_count + 1 ); if ( error ) goto Exit; /* restore subglyph pointer */ subglyph = gloader->base.subglyphs + num_base_subgs + n; if ( !( subglyph->flags & USE_MY_METRICS ) ) { loader->pp1 = pp[0]; loader->pp2 = pp[1]; loader->pp3 = pp[2]; loader->pp4 = pp[3]; } num_points = gloader->base.outline.n_points; if ( num_points == num_base_points ) continue; /* gloader->base.outline consists of three part: */ /* 0 -(1)-> start_point -(2)-> num_base_points -(3)-> n_points. */ /* */ /* (1): exist from the beginning */ /* (2): components that have been loaded so far */ /* (3): the newly loaded component */ TT_Process_Composite_Component( loader, subglyph, start_point, num_base_points ); } loader->stream = old_stream; /* process the glyph */ loader->ins_pos = ins_pos; if ( IS_HINTED( loader->load_flags ) &&#ifdef TT_USE_BYTECODE_INTERPRETER subglyph->flags & WE_HAVE_INSTR &&#endif num_points > start_point ) TT_Process_Composite_Glyph( loader, start_point, start_contour ); } } else { /* invalid composite count ( negative but not -1 ) */ error = TT_Err_Invalid_Outline; goto Exit; } /***********************************************************************/ /***********************************************************************/ /***********************************************************************/ Exit: if ( opened_frame ) face->forget_glyph_frame( loader );#ifdef FT_CONFIG_OPTION_INCREMENTAL if ( glyph_data_loaded ) face->root.internal->incremental_interface->funcs->free_glyph_data( face->root.internal->incremental_interface->object, &glyph_data );#endif return error; } static FT_Error compute_glyph_metrics( TT_Loader loader, FT_UInt glyph_index ) { FT_BBox bbox; TT_Face face = (TT_Face)loader->face; FT_Fixed y_scale; TT_GlyphSlot glyph = loader->glyph; TT_Size size = (TT_Size)loader->size; y_scale = 0x10000L; if ( ( loader->load_flags & FT_LOAD_NO_SCALE ) == 0 ) y_scale = size->root.metrics.y_scale; if ( glyph->format != FT_GLYPH_FORMAT_COMPOSITE ) FT_Outline_Get_CBox( &glyph->outline, &bbox ); else bbox = loader->bbox; /* get the device-independent horizontal advance. It is scaled later */ /* by the base layer. */ { FT_Pos advance = loader->linear; /* the flag FT_LOAD_IGNORE_GLOBAL_ADVANCE_WIDTH was introduced to */ /* correctly support DynaLab fonts, which have an incorrect */ /* `advance_Width_Max' field! It is used, to my knowledge, */ /* exclusively in the X-TrueType font server. */ /* */ if ( face->postscript.isFixedPitch && ( loader->load_flags & FT_LOAD_IGNORE_GLOBAL_ADVANCE_WIDTH ) == 0 ) advance = face->horizontal.advance_Width_Max; /* we need to return the advance in font units in linearHoriAdvance, */ /* it will be scaled later by the base layer. */ glyph->linearHoriAdvance = advance; } glyph->metrics.horiBearingX = bbox.xMin; glyph->metrics.horiBearingY = bbox.yMax; glyph->metrics.horiAdvance = loader->pp2.x - loader->pp1.x; /* Now take care of vertical metrics. In the case where there is */ /* no vertical information within the font (relatively common), make */ /* up some metrics by `hand'... */ { FT_Pos top; /* scaled vertical top side bearing */ FT_Pos advance; /* scaled vertical advance height */ /* Get the unscaled top bearing and advance height. */ if ( face->vertical_info && face->vertical.number_Of_VMetrics > 0 ) { top = (FT_Short)FT_DivFix( loader->pp3.y - bbox.yMax, y_scale ); if ( loader->pp3.y <= loader->pp4.y ) advance = 0; else advance = (FT_UShort)FT_DivFix( loader->pp3.y - loader->pp4.y,
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -