📄 ttgload.c
字号:
if ( n_ins > exec->face->maxProfile.maxSizeOfInstructions ) { PTRACE0(( "ERROR: Too many instructions in composite glyph %ld\n", subg->index )); return TT_Err_Too_Many_Ins; } if ( FILE_Read( exec->glyphIns, n_ins ) ) return error; error = Set_CodeRange( exec, TT_CodeRange_Glyph, exec->glyphIns, n_ins ); if ( error ) return error; } else n_ins = 0; /* prepare the execution context */ n_points += 2; exec->pts = subg->zone; pts = &exec->pts; pts->n_points = n_points; pts->n_contours = n_contours; /* add phantom points */ pts->cur[n_points - 2] = subg->pp1; pts->cur[n_points - 1] = subg->pp2; pts->touch[n_points - 1] = 0; pts->touch[n_points - 2] = 0; /* if hinting, round the phantom points */ if ( subg->is_hinted ) { pts->cur[n_points - 2].x = (subg->pp1.x + 32) & -64; pts->cur[n_points - 1].x = (subg->pp2.x + 32) & -64; } for ( k = 0; k < n_points; k++ ) pts->touch[k] &= TT_Flag_On_Curve; cur_to_org( n_points, pts ); /* now consider hinting */ if ( subg->is_hinted && n_ins > 0 ) { exec->is_composite = TRUE; exec->pedantic_hinting = load_flags & TTLOAD_PEDANTIC; error = Context_Run( exec, FALSE ); if (error && exec->pedantic_hinting) return error; } /* save glyph origin and advance points */ subg->pp1 = pts->cur[n_points - 2]; subg->pp2 = pts->cur[n_points - 1]; return TT_Err_Ok; }/******************************************************************* * * Function : Init_Glyph_Component * ******************************************************************/ static void Init_Glyph_Component( PSubglyph_Record element, PSubglyph_Record original, PExecution_Context exec ) { element->index = -1; element->is_scaled = FALSE; element->is_hinted = FALSE; if ( original ) mount_zone( &original->zone, &element->zone ); else element->zone = exec->pts; element->zone.n_contours = 0; element->zone.n_points = 0; element->arg1 = 0; element->arg2 = 0; element->element_flag = 0; element->preserve_pps = FALSE; element->transform.xx = 1L << 16; element->transform.xy = 0; element->transform.yx = 0; element->transform.yy = 1L << 16; element->transform.ox = 0; element->transform.oy = 0; element->metrics.horiBearingX = 0; element->metrics.horiAdvance = 0; } LOCAL_FUNC TT_Error Load_TrueType_Glyph( PInstance instance, PGlyph glyph, UShort glyph_index, UShort load_flags ) { enum TPhases_ { Load_Exit, Load_Glyph, Load_Header, Load_Simple, Load_Composite, Load_End }; typedef enum TPhases_ TPhases; DEFINE_ALL_LOCALS; PFace face; UShort num_points; Short num_contours; UShort left_points; Short left_contours; UShort num_elem_points; Long table; UShort load_top; Long k, l; UShort new_flags; Long index; UShort u, v; Long glyph_offset, offset; TT_F26Dot6 x, y, nx, ny; Fixed xx, xy, yx, yy; PExecution_Context exec; PSubglyph_Record subglyph, subglyph2; TGlyph_Zone base_pts; TPhases phase; PByte widths;/* TT_Glyph_Loader_Callback cacheCb; *//* TT_Outline cached_outline; */ /* first of all, check arguments */ if ( !glyph ) return TT_Err_Invalid_Glyph_Handle; face = glyph->face; if ( !face ) return TT_Err_Invalid_Glyph_Handle; if ( glyph_index >= face->numGlyphs ) return TT_Err_Invalid_Glyph_Index; if ( instance && (load_flags & TTLOAD_SCALE_GLYPH) == 0 ) { instance = 0; load_flags &= ~( TTLOAD_SCALE_GLYPH | TTLOAD_HINT_GLYPH ); } table = TT_LookUp_Table( face, TTAG_glyf ); if ( table < 0 ) { PTRACE0(( "ERROR: There is no glyph table in this font file!\n" )); return TT_Err_Glyf_Table_Missing; } glyph_offset = face->dirTables[table].Offset; /* query new execution context */ if ( instance && instance->debug ) exec = instance->context; else exec = New_Context( face ); if ( !exec ) return TT_Err_Could_Not_Find_Context; Context_Load( exec, face, instance ); if ( instance ) { if ( instance->GS.instruct_control & 2 ) exec->GS = Default_GraphicsState; else exec->GS = instance->GS; /* load default graphics state */ glyph->outline.high_precision = ( instance->metrics.y_ppem < 24 ); } /* save its critical pointers, as they'll be modified during load */ base_pts = exec->pts; /* init variables */ left_points = face->maxPoints; left_contours = face->maxContours; num_points = 0; num_contours = 0; load_top = 0; subglyph = exec->loadStack; Init_Glyph_Component( subglyph, NULL, exec ); subglyph->index = glyph_index; subglyph->is_hinted = load_flags & TTLOAD_HINT_GLYPH; /* when the cvt program has disabled hinting, the argument */ /* is ignored. */ if ( instance && instance->GS.instruct_control & 1 ) subglyph->is_hinted = FALSE; /* now access stream */ if ( USE_Stream( face->stream, stream ) ) goto Fin; /* Main loading loop */ phase = Load_Glyph; index = 0; while ( phase != Load_Exit ) { subglyph = exec->loadStack + load_top; switch ( phase ) { /************************************************************/ /* */ /* Load_Glyph state */ /* */ /* reading a glyph's generic header to determine */ /* whether it's simple or composite */ /* */ /* exit states: Load_Header and Load_End */ case Load_Glyph: /* check glyph index and table */ index = subglyph->index; if ( index < 0 || index >= face->numGlyphs ) { error = TT_Err_Invalid_Glyph_Index; goto Fail; } /* get horizontal metrics */ { Short left_bearing; UShort advance_width; Get_HMetrics( face, (UShort)index, !(load_flags & TTLOAD_IGNORE_GLOBAL_ADVANCE_WIDTH), &left_bearing, &advance_width ); subglyph->metrics.horiBearingX = left_bearing; subglyph->metrics.horiAdvance = advance_width; } phase = Load_Header; /* The cache callback isn't part of the FreeType release yet */ /* It is discarded for the moment.. */ /* */#if 0 if ( instance ) { /* is the glyph in an outline cache ? */ cacheCb = instance->owner->engine->glCallback; if ( cacheCb && 0 ) /* disabled */ { /* we have a callback */ error = cacheCb( instance->generic, index, &cached_outline, &x, &y ); if ( !error ) { /* no error, then append the outline to the current subglyph */ /* error = Append_Outline( subglyph, &left_points, &left_contours, &cached_outline ); */ phase = Load_End; } } }#endif break; /************************************************************/ /* */ /* Load_Header state */ /* */ /* reading a glyph's generic header to determine */ /* wether it's simple or composite */ /* */ /* exit states: Load_Simple and Load_Composite */ /* */ case Load_Header: /* load glyph */ if ( index + 1 < face->numLocations && face->glyphLocations[index] == face->glyphLocations[index + 1] ) { /* as described by Frederic Loyer, these are spaces, and */ /* not the unknown glyph. */ num_contours = 0; num_points = 0; subglyph->metrics.bbox.xMin = 0; subglyph->metrics.bbox.xMax = 0; subglyph->metrics.bbox.yMin = 0; subglyph->metrics.bbox.yMax = 0; subglyph->pp1.x = 0; subglyph->pp2.x = subglyph->metrics.horiAdvance; if (load_flags & TTLOAD_SCALE_GLYPH) subglyph->pp2.x = Scale_X( &exec->metrics, subglyph->pp2.x ); exec->glyphSize = 0; phase = Load_End; break; } offset = glyph_offset + face->glyphLocations[index]; /* read first glyph header */ if ( FILE_Seek( offset ) || ACCESS_Frame( 10L ) ) goto Fail_File; num_contours = GET_Short(); subglyph->metrics.bbox.xMin = GET_Short(); subglyph->metrics.bbox.yMin = GET_Short(); subglyph->metrics.bbox.xMax = GET_Short(); subglyph->metrics.bbox.yMax = GET_Short(); FORGET_Frame(); PTRACE6(( "Glyph %ld:\n", index )); PTRACE6(( " # of contours: %d\n", num_contours )); PTRACE6(( " xMin: %4d xMax: %4d\n", subglyph->metrics.bbox.xMin, subglyph->metrics.bbox.xMax )); PTRACE6(( " yMin: %4d yMax: %4d\n", subglyph->metrics.bbox.yMin, subglyph->metrics.bbox.yMax )); if ( num_contours > left_contours ) { PTRACE0(( "ERROR: Too many contours for glyph %ld\n", index )); error = TT_Err_Too_Many_Contours; goto Fail; } subglyph->pp1.x = subglyph->metrics.bbox.xMin - subglyph->metrics.horiBearingX; subglyph->pp1.y = 0; subglyph->pp2.x = subglyph->pp1.x + subglyph->metrics.horiAdvance; if (load_flags & TTLOAD_SCALE_GLYPH) { subglyph->pp1.x = Scale_X( &exec->metrics, subglyph->pp1.x ); subglyph->pp2.x = Scale_X( &exec->metrics, subglyph->pp2.x ); } /* is it a simple glyph ? */ if ( num_contours > 0 ) phase = Load_Simple; else phase = Load_Composite; break; /************************************************************/ /* */ /* Load_Simple state */ /* */ /* reading a simple glyph (num_contours must be set to */ /* the glyph's number of contours.) */ /* */ /* exit states : Load_End */ /* */ case Load_Simple: new_flags = load_flags; /* disable hinting when scaling */ if ( !subglyph->is_hinted ) new_flags &= ~TTLOAD_HINT_GLYPH; error = Load_Simple_Glyph( exec, stream, num_contours, left_contours, left_points, new_flags, subglyph ); if ( error ) goto Fail; /* Note: We could have put the simple loader source there */ /* but the code is fat enough already :-) */ num_points = exec->pts.n_points - 2; phase = Load_End; break; /************************************************************/ /* */ /* Load_Composite state */ /* */ /* reading a composite glyph header a pushing a new */ /* load element on the stack. */ /* */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -