ttgload.c
来自「Qt/Embedded是一个多平台的C++图形用户界面应用程序框架」· C语言 代码 · 共 1,332 行 · 第 1/3 页
C
1,332 行
return error; } /*************************************************************************/ /* */ /* <Function> */ /* load_truetype_glyph */ /* */ /* <Description> */ /* Loads a given truetype glyph. Handles composites and uses a */ /* TT_Loader object.. */ /* */ static TT_Error load_truetype_glyph( TT_Loader* loader, TT_UInt glyph_index ) { FT_Stream stream = loader->stream; TT_Error error; TT_Face face = loader->face; TT_ULong offset; FT_SubGlyph subglyphs[ TT_MAX_SUBGLYPHS ]; TT_Int num_subglyphs = 0, contours_count; TT_UInt index, num_points, num_contours, count; TT_Fixed x_scale, y_scale; TT_ULong ins_offset; /* check glyph index */ index = (TT_UInt)glyph_index; if ( index >= (TT_UInt)face->root.num_glyphs ) { error = TT_Err_Invalid_Glyph_Index; goto Fail; } loader->glyph_index = glyph_index; num_contours = 0; num_points = 0; ins_offset = 0; x_scale = 0x10000; y_scale = 0x10000; if ( (loader->load_flags & FT_LOAD_NO_SCALE)==0 ) { x_scale = loader->size->root.metrics.x_scale; y_scale = loader->size->root.metrics.y_scale; } /* get horizontal metrics */ { TT_Short left_bearing; TT_UShort advance_width; Get_HMetrics( face, index, (TT_Bool)!(loader->load_flags & FT_LOAD_IGNORE_GLOBAL_ADVANCE_WIDTH), &left_bearing, &advance_width ); loader->left_bearing = left_bearing; loader->advance = advance_width; } /* load glyph header */ offset = face->glyph_locations[index]; count = 0; if (index < (TT_UInt)face->num_locations-1) count = face->glyph_locations[index+1] - offset; 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; if ( (loader->load_flags & FT_LOAD_NO_SCALE)==0 ) loader->pp2.x = FT_MulFix( loader->pp2.x, x_scale );#ifdef TT_CONFIG_OPTION_BYTECODE_INTERPRETER if (loader->exec) loader->exec->glyphSize = 0;#endif goto Load_End; } offset = loader->glyf_offset + offset; /* read first glyph header */ if ( FILE_Seek( offset ) || ACCESS_Frame( 10L ) ) goto Fail; contours_count = GET_Short(); loader->bbox.xMin = GET_Short(); loader->bbox.yMin = GET_Short(); loader->bbox.xMax = GET_Short(); loader->bbox.yMax = GET_Short(); FORGET_Frame(); FT_TRACE6(( "Glyph %ld\n", index )); FT_TRACE6(( " # of contours : %d\n", num_contours )); FT_TRACE6(( " xMin: %4d xMax: %4d\n", loader->bbox.xMin, loader->bbox.xMax )); FT_TRACE6(( " yMin: %4d yMax: %4d\n", loader->bbox.yMin, loader->bbox.yMax )); FT_TRACE6(( "-" )); count -= 10; if ( contours_count > loader->left_contours ) { FT_TRACE0(( "ERROR: Too many contours for glyph %ld\n", index )); error = TT_Err_Too_Many_Contours; goto Fail; } loader->pp1.x = loader->bbox.xMin - loader->left_bearing; loader->pp1.y = 0; loader->pp2.x = loader->pp1.x + loader->advance; loader->pp2.y = 0; 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 ); } /*************************************************************************/ /*************************************************************************/ /*************************************************************************/ /**********************************************************************/ /* if it is a simple glyph, load it */ if (contours_count >= 0) { TT_UInt num_base_points; #ifdef TT_CONFIG_OPTION_BYTECODE_INTERPRETER error = Load_Simple( loader, count, contours_count, (TT_Bool)( loader->size && loader->size->debug ) );#else error = Load_Simple( loader, count, contours_count, 0 );#endif if ( error ) goto Fail; /* Note: We could have put the simple loader source there */ /* but the code is fat enough already :-) */ num_points = loader->zone.n_points; num_contours = loader->zone.n_contours; num_base_points = loader->base.n_points; { TT_UInt k; for ( k = 0; k < num_contours; k++ ) loader->zone.contours[k] += num_base_points; } loader->base.n_points += num_points; loader->base.n_contours += num_contours; loader->zone.n_points = 0; loader->zone.n_contours = 0; loader->left_points -= num_points; loader->left_contours -= num_contours; } /*************************************************************************/ /*************************************************************************/ /*************************************************************************/ /************************************************************************/ else /* otherwise, load a composite !! */ { /* for each subglyph, read composite header */ FT_SubGlyph* subglyph = subglyphs; if (ACCESS_Frame(count)) goto Fail; num_subglyphs = 0; do { TT_Fixed xx, xy, yy, yx; subglyph->arg1 = subglyph->arg2 = 0; subglyph->flags = GET_UShort(); subglyph->index = GET_UShort(); /* read arguments */ if (subglyph->flags & ARGS_ARE_WORDS) { subglyph->arg1 = GET_Short(); subglyph->arg2 = GET_Short(); } else { subglyph->arg1 = GET_Char(); subglyph->arg2 = GET_Char(); } /* read transform */ xx = yy = 0x10000; xy = yx = 0; if (subglyph->flags & WE_HAVE_A_SCALE) { xx = (TT_Fixed)GET_Short() << 2; yy = xx; } else if (subglyph->flags & WE_HAVE_AN_XY_SCALE) { xx = (TT_Fixed)GET_Short() << 2; yy = (TT_Fixed)GET_Short() << 2; } else if (subglyph->flags & WE_HAVE_A_2X2) { xx = (TT_Fixed)GET_Short() << 2; xy = (TT_Fixed)GET_Short() << 2; yx = (TT_Fixed)GET_Short() << 2; yy = (TT_Fixed)GET_Short() << 2; } subglyph->transform.xx = xx; subglyph->transform.xy = xy; subglyph->transform.yx = yx; subglyph->transform.yy = yy; subglyph++; num_subglyphs++; if (num_subglyphs >= TT_MAX_SUBGLYPHS) break; } while (subglyph[-1].flags & MORE_COMPONENTS);#ifdef TT_CONFIG_OPTION_BYTECODE_INTERPRETER { /* we must undo the ACCESS_Frame in order to point to the */ /* composite instructions, if we find some .. */ /* we will process them later.. */ ins_offset = FILE_Pos() + stream->cursor - stream->limit; FORGET_Frame(); }#endif /*************************************************************************/ /*************************************************************************/ /*************************************************************************/ /*********************************************************************/ /* Now, read each subglyph independently.. */ { TT_Int n, num_base_points, num_new_points; subglyph = subglyphs; for ( n = 0; n < num_subglyphs; n++, subglyph++ ) { TT_Vector pp1, pp2; TT_Pos x, y; pp1 = loader->pp1; pp2 = loader->pp2; num_base_points = loader->base.n_points; error = load_truetype_glyph( loader, subglyph->index ); if ( subglyph->flags & USE_MY_METRICS ) { pp1 = loader->pp1; pp2 = loader->pp2; } else { loader->pp1 = pp1; loader->pp2 = pp2; } num_points = loader->base.n_points; num_contours = loader->base.n_contours; num_new_points = num_points - num_base_points; /********************************************************/ /* now perform the transform required for this subglyph */ if ( subglyph->flags & ( WE_HAVE_A_SCALE | WE_HAVE_AN_XY_SCALE | WE_HAVE_A_2X2 ) ) { TT_Vector* cur = loader->zone.cur; TT_Vector* org = loader->zone.org; TT_Vector* limit = cur + num_new_points; for ( ; cur < limit; cur++, org++ ) { TT_Pos nx, ny; nx = FT_MulFix( cur->x, subglyph->transform.xx ) + FT_MulFix( cur->y, subglyph->transform.yx ); ny = FT_MulFix( cur->x, subglyph->transform.xy ) + FT_MulFix( cur->y, subglyph->transform.yy ); cur->x = nx; cur->y = ny; nx = FT_MulFix( org->x, subglyph->transform.xx ) + FT_MulFix( org->y, subglyph->transform.yx ); ny = FT_MulFix( org->x, subglyph->transform.xy ) + FT_MulFix( org->y, subglyph->transform.yy ); org->x = nx; org->y = ny; } } /* apply offset */ if ( !(subglyph->flags & ARGS_ARE_XY_VALUES) ) { TT_Int k = subglyph->arg1; TT_UInt l = subglyph->arg2; if ( k >= num_base_points || l >= (TT_UInt)num_new_points ) { error = TT_Err_Invalid_Composite; goto Fail; } l += num_base_points; x = loader->base.cur[k].x - loader->base.cur[l].x; y = loader->base.cur[k].y - loader->base.cur[l].y; } else { x = subglyph->arg1; y = subglyph->arg2; if (!(loader->load_flags & FT_LOAD_NO_SCALE)) { x = FT_MulFix( x, x_scale ); y = FT_MulFix( y, y_scale ); if ( subglyph->flags & ROUND_XY_TO_GRID ) { x = (x + 32) & -64; y = (y + 32) & -64; } } } translate_array( num_new_points, loader->zone.cur, x, y ); cur_to_org( num_new_points, &loader->zone ); } /*************************************************************************/ /*************************************************************************/ /*************************************************************************/ /* we have finished loading all sub-glyphs, now, look for */ /* instructions for this composite !! */#ifdef TT_CONFIG_OPTION_BYTECODE_INTERPRETER subglyph--; if (num_subglyphs > 0 && loader->exec && subglyph->flags & WE_HAVE_INSTR) { TT_UShort n_ins; TT_ExecContext exec = loader->exec; TT_UInt n_points = loader->base.n_points; FT_GlyphZone* pts; TT_Vector* pp1; /* read size of instructions */ if ( FILE_Seek( ins_offset ) || READ_UShort(n_ins) ) goto Fail; FT_TRACE4(( "Instructions size = %d\n", n_ins )); /* check it */ if ( n_ins > face->max_profile.maxSizeOfInstructions ) { FT_TRACE0(( "Too many instructions in composite glyph %ld\n", subglyph->index )); return TT_Err_Too_Many_Ins; } if (exec) { } /* read the instructions */ if ( FILE_Read( exec->glyphIns, n_ins ) ) goto Fail; error = TT_Set_CodeRange( exec, tt_coderange_glyph, exec->glyphIns, n_ins ); if ( error ) goto Fail; /* prepare the execution context */ exec->pts = loader->base; pts = &exec->pts; pts->n_points = num_points + 2; pts->n_contours = num_contours; /* add phantom points */ pp1 = pts->cur + num_points; pp1[0] = loader->pp1; pp1[1] = loader->pp2; pts->tags[num_points + 1] = 0; pts->tags[num_points + 2] = 0; /* if hinting, round the phantom points */ if ( IS_HINTED(loader->load_flags) ) { pp1[0].x = ((loader->pp1.x + 32) & -64); pp1[1].x = ((loader->pp2.x + 32) & -64); } { TT_UInt k; for ( k = 0; k < n_points; k++ ) pts->tags[k] &= FT_Curve_Tag_On; }
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?