📄 pfrobjs.c
字号:
error = pfr_slot_load_bitmap( slot, size, gindex ); if ( error == 0 ) goto Exit; } if ( load_flags & FT_LOAD_SBITS_ONLY ) { error = PFR_Err_Invalid_Argument; goto Exit; } gchar = face->phy_font.chars + gindex; pfrslot->format = FT_GLYPH_FORMAT_OUTLINE; outline->n_points = 0; outline->n_contours = 0; gps_offset = face->header.gps_section_offset; /* load the glyph outline (FT_LOAD_NO_RECURSE isn't supported) */ error = pfr_glyph_load( &slot->glyph, face->root.stream, gps_offset, gchar->gps_offset, gchar->gps_size ); if ( !error ) { FT_BBox cbox; FT_Glyph_Metrics* metrics = &pfrslot->metrics; FT_Pos advance; FT_Int em_metrics, em_outline; FT_Bool scaling; scaling = FT_BOOL( ( load_flags & FT_LOAD_NO_SCALE ) == 0 ); /* copy outline data */ *outline = slot->glyph.loader->base.outline; outline->flags &= ~FT_OUTLINE_OWNER; outline->flags |= FT_OUTLINE_REVERSE_FILL; if ( size && pfrsize->metrics.y_ppem < 24 ) outline->flags |= FT_OUTLINE_HIGH_PRECISION; /* compute the advance vector */ metrics->horiAdvance = 0; metrics->vertAdvance = 0; advance = gchar->advance; em_metrics = face->phy_font.metrics_resolution; em_outline = face->phy_font.outline_resolution; if ( em_metrics != em_outline ) advance = FT_MulDiv( advance, em_outline, em_metrics ); if ( face->phy_font.flags & PFR_PHY_VERTICAL ) metrics->vertAdvance = advance; else metrics->horiAdvance = advance; pfrslot->linearHoriAdvance = metrics->horiAdvance; pfrslot->linearVertAdvance = metrics->vertAdvance; /* make-up vertical metrics(?) */ metrics->vertBearingX = 0; metrics->vertBearingY = 0;#if 0 /* some fonts seem to be broken here! */ /* Apply the font matrix, if any. */ /* TODO: Test existing fonts with unusual matrix */ /* whether we have to adjust Units per EM. */ { FT_Matrix font_matrix; font_matrix.xx = face->log_font.matrix[0] << 8; font_matrix.yx = face->log_font.matrix[1] << 8; font_matrix.xy = face->log_font.matrix[2] << 8; font_matrix.yy = face->log_font.matrix[3] << 8; FT_Outline_Transform( outline, &font_matrix ); }#endif /* scale when needed */ if ( scaling ) { FT_Int n; FT_Fixed x_scale = pfrsize->metrics.x_scale; FT_Fixed y_scale = pfrsize->metrics.y_scale; FT_Vector* vec = outline->points; /* scale outline points */ for ( n = 0; n < outline->n_points; n++, vec++ ) { vec->x = FT_MulFix( vec->x, x_scale ); vec->y = FT_MulFix( vec->y, y_scale ); } /* scale the advance */ metrics->horiAdvance = FT_MulFix( metrics->horiAdvance, x_scale ); metrics->vertAdvance = FT_MulFix( metrics->vertAdvance, y_scale ); } /* compute the rest of the metrics */ FT_Outline_Get_CBox( outline, &cbox ); metrics->width = cbox.xMax - cbox.xMin; metrics->height = cbox.yMax - cbox.yMin; metrics->horiBearingX = cbox.xMin; metrics->horiBearingY = cbox.yMax - metrics->height; } Exit: return error; } /*************************************************************************/ /*************************************************************************/ /***** *****/ /***** KERNING METHOD *****/ /***** *****/ /*************************************************************************/ /*************************************************************************/#ifdef FT_OPTIMIZE_MEMORY FT_LOCAL_DEF( FT_Error ) pfr_face_get_kerning( FT_Face pfrface, /* PFR_Face */ FT_UInt glyph1, FT_UInt glyph2, FT_Vector* kerning ) { PFR_Face face = (PFR_Face)pfrface; FT_Error error = PFR_Err_Ok; PFR_PhyFont phy_font = &face->phy_font; FT_UInt32 code1, code2, pair; kerning->x = 0; kerning->y = 0; if ( glyph1 > 0 ) glyph1--; if ( glyph2 > 0 ) glyph2--; /* convert glyph indices to character codes */ if ( glyph1 > phy_font->num_chars || glyph2 > phy_font->num_chars ) goto Exit; code1 = phy_font->chars[glyph1].char_code; code2 = phy_font->chars[glyph2].char_code; pair = PFR_KERN_INDEX( code1, code2 ); /* now search the list of kerning items */ { PFR_KernItem item = phy_font->kern_items; FT_Stream stream = pfrface->stream; for ( ; item; item = item->next ) { if ( pair >= item->pair1 && pair <= item->pair2 ) goto FoundPair; } goto Exit; FoundPair: /* we found an item, now parse it and find the value if any */ if ( FT_STREAM_SEEK( item->offset ) || FT_FRAME_ENTER( item->pair_count * item->pair_size ) ) goto Exit; { FT_UInt count = item->pair_count; FT_UInt size = item->pair_size; FT_UInt power = (FT_UInt)ft_highpow2( (FT_UInt32)count ); FT_UInt probe = power * size; FT_UInt extra = count - power; FT_Byte* base = stream->cursor; FT_Bool twobytes = item->flags & 1; FT_Byte* p; FT_UInt32 cpair; if ( extra > 0 ) { p = base + extra * size; if ( twobytes ) cpair = FT_NEXT_ULONG( p ); else cpair = PFR_NEXT_KPAIR( p ); if ( cpair == pair ) goto Found; if ( cpair < pair ) base = p; } while ( probe > size ) { probe >>= 1; p = base + probe; if ( twobytes ) cpair = FT_NEXT_ULONG( p ); else cpair = PFR_NEXT_KPAIR( p ); if ( cpair == pair ) goto Found; if ( cpair < pair ) base += probe; } p = base; if ( twobytes ) cpair = FT_NEXT_ULONG( p ); else cpair = PFR_NEXT_KPAIR( p ); if ( cpair == pair ) { FT_Int value; Found: if ( item->flags & 2 ) value = FT_PEEK_SHORT( p ); else value = p[0]; kerning->x = item->base_adj + value; } } FT_FRAME_EXIT(); } Exit: return error; }#else /* !FT_OPTIMIZE_MEMORY */ FT_LOCAL_DEF( FT_Error ) pfr_face_get_kerning( FT_Face pfrface, /* PFR_Face */ FT_UInt glyph1, FT_UInt glyph2, FT_Vector* kerning ) { PFR_Face face = (PFR_Face)pfrface; FT_Error error = PFR_Err_Ok; PFR_PhyFont phy_font = &face->phy_font; PFR_KernPair pairs = phy_font->kern_pairs; FT_UInt32 idx = PFR_KERN_INDEX( glyph1, glyph2 ); FT_UInt min, max; kerning->x = 0; kerning->y = 0; min = 0; max = phy_font->num_kern_pairs; while ( min < max ) { FT_UInt mid = ( min + max ) >> 1; PFR_KernPair pair = pairs + mid; FT_UInt32 pidx = PFR_KERN_PAIR_INDEX( pair ); if ( pidx == idx ) { kerning->x = pair->kerning; break; } if ( pidx < idx ) min = mid + 1; else max = mid; } return error; }#endif /* !FT_OPTIMIZE_MEMORY *//* END */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -