+ + + + /*************************************************************************/ + /* */ + /* */ + /* cff_face_get_metrics */ + /* */ + /* */ + /* Returns the horizontal or vertical metrics in font units for a */ + /* given glyph. The metrics are the left side bearing (resp. top */ + /* side bearing) and advance width (resp. advance height). */ + /* */ + /* */ + /* header :: A pointer to either the horizontal or vertical metrics */ + /* structure. */ + /* */ + /* idx :: The glyph index. */ + /* */ + /* */ + /* bearing :: The bearing, either left side or top side. */ + /* */ + /* advance :: The advance width resp. advance height. */ + /* */ + /* */ + /* This function will much probably move to another component in the */ + /* near future, but I haven't decided which yet. */ + /* */ +#ifdef FT_OPTIMIZE_MEMORY + + static void + cff_face_get_metrics( TT_Face face, + FT_Bool vertical, + FT_UInt idx, + FT_Short *abearing, + FT_UShort *aadvance ) + { + TT_HoriHeader* header; + FT_Byte* p; + FT_Byte* limit; + FT_UShort k; + + + if ( vertical ) + { + header = (TT_HoriHeader*)&face->vertical; + p = face->vert_metrics; + limit = p + face->vert_metrics_size; + } + else + { + header = &face->horizontal; + p = face->horz_metrics; + limit = p + face->horz_metrics_size; + } + + k = header->number_Of_HMetrics; + + if ( k > 0 ) + { + if ( idx < (FT_UInt)k ) + { + p += 4 * idx; + if ( p + 4 > limit ) + goto NoData; + + *aadvance = FT_NEXT_USHORT( p ); + *abearing = FT_NEXT_SHORT( p ); + } + else + { + p += 4 * ( k - 1 ); + if ( p + 4 > limit ) + goto NoData; + + *aadvance = FT_NEXT_USHORT( p ); + p += 2 + 2 * ( idx - k ); + if ( p + 2 > limit ) + *abearing = 0; + else + *abearing = FT_PEEK_SHORT( p ); + } + } + else + { + NoData: + *abearing = 0; + *aadvance = 0; + } + } + +#else /* !FT_OPTIMIZE_MEMORY */ + + static void + cff_face_get_metrics( TT_Face face, + FT_Bool vertical, + FT_UInt idx, + FT_Short *abearing, + FT_UShort *aadvance ) + { + TT_HoriHeader* header = vertical ? (TT_HoriHeader*)&face->vertical + : &face->horizontal; + TT_LongMetrics longs_m; + FT_UShort k = header->number_Of_HMetrics; + + + if ( k == 0 ) + { + *abearing = *aadvance = 0; + return; + } + + if ( idx < (FT_UInt)k ) + { + longs_m = (TT_LongMetrics)header->long_metrics + idx; + *abearing = longs_m->bearing; + *aadvance = longs_m->advance; + } + else + { + *abearing = ((TT_ShortMetrics*)header->short_metrics)[idx - k]; + *aadvance = ((TT_LongMetrics)header->long_metrics)[k - 1].advance; + } + } + +#endif /* !FT_OPTIMIZE_MEMORY */ + + + + + + + + + + + + static FT_Error cff_get_glyph_data( TT_Face face, FT_UInt glyph_index, @@ -2515,6 +2653,22 @@ metrics->vertBearingY = 0; metrics->vertAdvance = 0; + //Go get the vertical metrics from the vtmx table if we have one. + if(face->vertical_info + && face->vertical.number_Of_VMetrics > 0 + && face->vertical.long_metrics != 0) + { + FT_Short vertBearingY=0; + FT_UShort vertAdvance=0; + cff_face_get_metrics(face, + 1, + glyph_index, + &vertBearingY, + &vertAdvance); + metrics->vertBearingY = vertBearingY; + metrics->vertAdvance = vertAdvance; + } + glyph->root.linearVertAdvance = 0; glyph->root.format = FT_GLYPH_FORMAT_OUTLINE;