1ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov/***************************************************************************/ 2ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov/* */ 3ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov/* t1gload.c */ 4ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov/* */ 5ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov/* Type 1 Glyph Loader (body). */ 6ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov/* */ 7ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov/* Copyright 1996-2006, 2008-2010, 2013 by */ 8ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov/* David Turner, Robert Wilhelm, and Werner Lemberg. */ 9ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov/* */ 10ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov/* This file is part of the FreeType project, and may only be used, */ 11ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov/* modified, and distributed under the terms of the FreeType project */ 12ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov/* license, LICENSE.TXT. By continuing to use, modify, or distribute */ 13ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov/* this file you indicate that you have read the license and */ 14ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov/* understand and accept it fully. */ 15ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov/* */ 16ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov/***************************************************************************/ 17ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 18ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 19ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov#include "../../include/ft2build.h" 20ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov#include "t1gload.h" 21ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov#include "../../include/freetype/internal/ftcalc.h" 22ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov#include "../../include/freetype/internal/ftdebug.h" 23ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov#include "../../include/freetype/internal/ftstream.h" 24ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov#include "../../include/freetype/ftoutln.h" 25ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov#include "../../include/freetype/internal/psaux.h" 26ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 27ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov#include "t1errors.h" 28ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 29ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 30ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /*************************************************************************/ 31ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* */ 32ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* The macro FT_COMPONENT is used in trace mode. It is an implicit */ 33ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* parameter of the FT_TRACE() and FT_ERROR() macros, used to print/log */ 34ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* messages during execution. */ 35ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* */ 36ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov#undef FT_COMPONENT 37ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov#define FT_COMPONENT trace_t1gload 38ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 39ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 40ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /*************************************************************************/ 41ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /*************************************************************************/ 42ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /*************************************************************************/ 43ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /********** *********/ 44ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /********** COMPUTE THE MAXIMUM ADVANCE WIDTH *********/ 45ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /********** *********/ 46ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /********** The following code is in charge of computing *********/ 47ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /********** the maximum advance width of the font. It *********/ 48ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /********** quickly processes each glyph charstring to *********/ 49ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /********** extract the value from either a `sbw' or `seac' *********/ 50ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /********** operator. *********/ 51ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /********** *********/ 52ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /*************************************************************************/ 53ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /*************************************************************************/ 54ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /*************************************************************************/ 55ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 56ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 57ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_LOCAL_DEF( FT_Error ) 58ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov T1_Parse_Glyph_And_Get_Char_String( T1_Decoder decoder, 59ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_UInt glyph_index, 60ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_Data* char_string ) 61ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 62ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov T1_Face face = (T1_Face)decoder->builder.face; 63ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov T1_Font type1 = &face->type1; 64ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_Error error = FT_Err_Ok; 65ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 66ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov#ifdef FT_CONFIG_OPTION_INCREMENTAL 67ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_Incremental_InterfaceRec *inc = 68ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov face->root.internal->incremental_interface; 69ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov#endif 70ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 71ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 72ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov decoder->font_matrix = type1->font_matrix; 73ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov decoder->font_offset = type1->font_offset; 74ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 75ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov#ifdef FT_CONFIG_OPTION_INCREMENTAL 76ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 77ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* For incremental fonts get the character data using the */ 78ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* callback function. */ 79ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( inc ) 80ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov error = inc->funcs->get_glyph_data( inc->object, 81ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov glyph_index, char_string ); 82ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov else 83ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 84ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov#endif /* FT_CONFIG_OPTION_INCREMENTAL */ 85ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 86ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* For ordinary fonts get the character data stored in the face record. */ 87ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 88ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov char_string->pointer = type1->charstrings[glyph_index]; 89ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov char_string->length = (FT_Int)type1->charstrings_len[glyph_index]; 90ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 91ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 92ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( !error ) 93ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov error = decoder->funcs.parse_charstrings( 94ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov decoder, (FT_Byte*)char_string->pointer, 95ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov char_string->length ); 96ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 97ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov#ifdef FT_CONFIG_OPTION_INCREMENTAL 98ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 99ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* Incremental fonts can optionally override the metrics. */ 100ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( !error && inc && inc->funcs->get_glyph_metrics ) 101ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 102ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_Incremental_MetricsRec metrics; 103ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 104ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 105ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov metrics.bearing_x = FIXED_TO_INT( decoder->builder.left_bearing.x ); 106ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov metrics.bearing_y = 0; 107ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov metrics.advance = FIXED_TO_INT( decoder->builder.advance.x ); 108ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov metrics.advance_v = FIXED_TO_INT( decoder->builder.advance.y ); 109ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 110ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov error = inc->funcs->get_glyph_metrics( inc->object, 111ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov glyph_index, FALSE, &metrics ); 112ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 113ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov decoder->builder.left_bearing.x = INT_TO_FIXED( metrics.bearing_x ); 114ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov decoder->builder.advance.x = INT_TO_FIXED( metrics.advance ); 115ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov decoder->builder.advance.y = INT_TO_FIXED( metrics.advance_v ); 116ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 117ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 118ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov#endif /* FT_CONFIG_OPTION_INCREMENTAL */ 119ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 120ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov return error; 121ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 122ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 123ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 124ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_CALLBACK_DEF( FT_Error ) 125ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov T1_Parse_Glyph( T1_Decoder decoder, 126ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_UInt glyph_index ) 127ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 128ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_Data glyph_data; 129ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_Error error = T1_Parse_Glyph_And_Get_Char_String( 130ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov decoder, glyph_index, &glyph_data ); 131ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 132ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 133ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov#ifdef FT_CONFIG_OPTION_INCREMENTAL 134ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 135ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( !error ) 136ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 137ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov T1_Face face = (T1_Face)decoder->builder.face; 138ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 139ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 140ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( face->root.internal->incremental_interface ) 141ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov face->root.internal->incremental_interface->funcs->free_glyph_data( 142ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov face->root.internal->incremental_interface->object, 143ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov &glyph_data ); 144ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 145ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 146ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov#endif /* FT_CONFIG_OPTION_INCREMENTAL */ 147ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 148ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov return error; 149ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 150ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 151ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 152ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_LOCAL_DEF( FT_Error ) 153ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov T1_Compute_Max_Advance( T1_Face face, 154ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_Pos* max_advance ) 155ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 156ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_Error error; 157ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov T1_DecoderRec decoder; 158ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_Int glyph_index; 159ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov T1_Font type1 = &face->type1; 160ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov PSAux_Service psaux = (PSAux_Service)face->psaux; 161ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 162ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 163ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_ASSERT( ( face->len_buildchar == 0 ) == ( face->buildchar == NULL ) ); 164ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 165ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov *max_advance = 0; 166ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 167ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* initialize load decoder */ 168ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov error = psaux->t1_decoder_funcs->init( &decoder, 169ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov (FT_Face)face, 170ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 0, /* size */ 171ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 0, /* glyph slot */ 172ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov (FT_Byte**)type1->glyph_names, 173ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov face->blend, 174ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 0, 175ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_RENDER_MODE_NORMAL, 176ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov T1_Parse_Glyph ); 177ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( error ) 178ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov return error; 179ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 180ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov decoder.builder.metrics_only = 1; 181ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov decoder.builder.load_points = 0; 182ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 183ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov decoder.num_subrs = type1->num_subrs; 184ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov decoder.subrs = type1->subrs; 185ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov decoder.subrs_len = type1->subrs_len; 186ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 187ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov decoder.buildchar = face->buildchar; 188ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov decoder.len_buildchar = face->len_buildchar; 189ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 190ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov *max_advance = 0; 191ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 192ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* for each glyph, parse the glyph charstring and extract */ 193ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* the advance width */ 194ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov for ( glyph_index = 0; glyph_index < type1->num_glyphs; glyph_index++ ) 195ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 196ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* now get load the unscaled outline */ 197ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov error = T1_Parse_Glyph( &decoder, glyph_index ); 198ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( glyph_index == 0 || decoder.builder.advance.x > *max_advance ) 199ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov *max_advance = decoder.builder.advance.x; 200ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 201ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* ignore the error if one occurred - skip to next glyph */ 202ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 203ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 204ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov psaux->t1_decoder_funcs->done( &decoder ); 205ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 206ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov return FT_Err_Ok; 207ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 208ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 209ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 210ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_LOCAL_DEF( FT_Error ) 211ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov T1_Get_Advances( FT_Face t1face, /* T1_Face */ 212ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_UInt first, 213ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_UInt count, 214ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_Int32 load_flags, 215ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_Fixed* advances ) 216ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 217ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov T1_Face face = (T1_Face)t1face; 218ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov T1_DecoderRec decoder; 219ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov T1_Font type1 = &face->type1; 220ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov PSAux_Service psaux = (PSAux_Service)face->psaux; 221ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_UInt nn; 222ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_Error error; 223ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 224ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 225ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( load_flags & FT_LOAD_VERTICAL_LAYOUT ) 226ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 227ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov for ( nn = 0; nn < count; nn++ ) 228ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov advances[nn] = 0; 229ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 230ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov return FT_Err_Ok; 231ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 232ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 233ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov error = psaux->t1_decoder_funcs->init( &decoder, 234ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov (FT_Face)face, 235ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 0, /* size */ 236ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 0, /* glyph slot */ 237ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov (FT_Byte**)type1->glyph_names, 238ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov face->blend, 239ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 0, 240ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_RENDER_MODE_NORMAL, 241ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov T1_Parse_Glyph ); 242ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( error ) 243ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov return error; 244ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 245ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov decoder.builder.metrics_only = 1; 246ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov decoder.builder.load_points = 0; 247ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 248ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov decoder.num_subrs = type1->num_subrs; 249ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov decoder.subrs = type1->subrs; 250ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov decoder.subrs_len = type1->subrs_len; 251ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 252ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov decoder.buildchar = face->buildchar; 253ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov decoder.len_buildchar = face->len_buildchar; 254ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 255ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov for ( nn = 0; nn < count; nn++ ) 256ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 257ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov error = T1_Parse_Glyph( &decoder, first + nn ); 258ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( !error ) 259ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov advances[nn] = FIXED_TO_INT( decoder.builder.advance.x ); 260ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov else 261ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov advances[nn] = 0; 262ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 263ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 264ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov return FT_Err_Ok; 265ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 266ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 267ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 268ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_LOCAL_DEF( FT_Error ) 269ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov T1_Load_Glyph( FT_GlyphSlot t1glyph, /* T1_GlyphSlot */ 270ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_Size t1size, /* T1_Size */ 271ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_UInt glyph_index, 272ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_Int32 load_flags ) 273ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 274ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov T1_GlyphSlot glyph = (T1_GlyphSlot)t1glyph; 275ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_Error error; 276ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov T1_DecoderRec decoder; 277ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov T1_Face face = (T1_Face)t1glyph->face; 278ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_Bool hinting; 279ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov T1_Font type1 = &face->type1; 280ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov PSAux_Service psaux = (PSAux_Service)face->psaux; 281ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov const T1_Decoder_Funcs decoder_funcs = psaux->t1_decoder_funcs; 282ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 283ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_Matrix font_matrix; 284ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_Vector font_offset; 285ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_Data glyph_data; 286ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_Bool must_finish_decoder = FALSE; 287ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov#ifdef FT_CONFIG_OPTION_INCREMENTAL 288ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_Bool glyph_data_loaded = 0; 289ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov#endif 290ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 291ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 292ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov#ifdef FT_CONFIG_OPTION_INCREMENTAL 293ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( glyph_index >= (FT_UInt)face->root.num_glyphs && 294ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov !face->root.internal->incremental_interface ) 295ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov#else 296ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( glyph_index >= (FT_UInt)face->root.num_glyphs ) 297ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov#endif /* FT_CONFIG_OPTION_INCREMENTAL */ 298ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 299ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov error = FT_THROW( Invalid_Argument ); 300ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov goto Exit; 301ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 302ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 303ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_ASSERT( ( face->len_buildchar == 0 ) == ( face->buildchar == NULL ) ); 304ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 305ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( load_flags & FT_LOAD_NO_RECURSE ) 306ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov load_flags |= FT_LOAD_NO_SCALE | FT_LOAD_NO_HINTING; 307ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 308ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( t1size ) 309ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 310ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov glyph->x_scale = t1size->metrics.x_scale; 311ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov glyph->y_scale = t1size->metrics.y_scale; 312ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 313ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov else 314ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 315ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov glyph->x_scale = 0x10000L; 316ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov glyph->y_scale = 0x10000L; 317ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 318ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 319ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov t1glyph->outline.n_points = 0; 320ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov t1glyph->outline.n_contours = 0; 321ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 322ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov hinting = FT_BOOL( ( load_flags & FT_LOAD_NO_SCALE ) == 0 && 323ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov ( load_flags & FT_LOAD_NO_HINTING ) == 0 ); 324ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 325ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov t1glyph->format = FT_GLYPH_FORMAT_OUTLINE; 326ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 327ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov error = decoder_funcs->init( &decoder, 328ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov t1glyph->face, 329ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov t1size, 330ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov t1glyph, 331ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov (FT_Byte**)type1->glyph_names, 332ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov face->blend, 333ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_BOOL( hinting ), 334ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_LOAD_TARGET_MODE( load_flags ), 335ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov T1_Parse_Glyph ); 336ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( error ) 337ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov goto Exit; 338ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 339ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov must_finish_decoder = TRUE; 340ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 341ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov decoder.builder.no_recurse = FT_BOOL( 342ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov ( load_flags & FT_LOAD_NO_RECURSE ) != 0 ); 343ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 344ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov decoder.num_subrs = type1->num_subrs; 345ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov decoder.subrs = type1->subrs; 346ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov decoder.subrs_len = type1->subrs_len; 347ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 348ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov decoder.buildchar = face->buildchar; 349ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov decoder.len_buildchar = face->len_buildchar; 350ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 351ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* now load the unscaled outline */ 352ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov error = T1_Parse_Glyph_And_Get_Char_String( &decoder, glyph_index, 353ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov &glyph_data ); 354ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( error ) 355ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov goto Exit; 356ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov#ifdef FT_CONFIG_OPTION_INCREMENTAL 357ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov glyph_data_loaded = 1; 358ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov#endif 359ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 360ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov font_matrix = decoder.font_matrix; 361ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov font_offset = decoder.font_offset; 362ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 363ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* save new glyph tables */ 364ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov decoder_funcs->done( &decoder ); 365ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 366ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov must_finish_decoder = FALSE; 367ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 368ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* now, set the metrics -- this is rather simple, as */ 369ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* the left side bearing is the xMin, and the top side */ 370ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* bearing the yMax */ 371ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( !error ) 372ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 373ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov t1glyph->outline.flags &= FT_OUTLINE_OWNER; 374ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov t1glyph->outline.flags |= FT_OUTLINE_REVERSE_FILL; 375ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 376ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* for composite glyphs, return only left side bearing and */ 377ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* advance width */ 378ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( load_flags & FT_LOAD_NO_RECURSE ) 379ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 380ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_Slot_Internal internal = t1glyph->internal; 381ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 382ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 383ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov t1glyph->metrics.horiBearingX = 384ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FIXED_TO_INT( decoder.builder.left_bearing.x ); 385ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov t1glyph->metrics.horiAdvance = 386ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FIXED_TO_INT( decoder.builder.advance.x ); 387ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 388ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov internal->glyph_matrix = font_matrix; 389ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov internal->glyph_delta = font_offset; 390ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov internal->glyph_transformed = 1; 391ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 392ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov else 393ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 394ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_BBox cbox; 395ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_Glyph_Metrics* metrics = &t1glyph->metrics; 396ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_Vector advance; 397ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 398ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 399ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* copy the _unscaled_ advance width */ 400ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov metrics->horiAdvance = 401ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FIXED_TO_INT( decoder.builder.advance.x ); 402ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov t1glyph->linearHoriAdvance = 403ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FIXED_TO_INT( decoder.builder.advance.x ); 404ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov t1glyph->internal->glyph_transformed = 0; 405ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 406ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( load_flags & FT_LOAD_VERTICAL_LAYOUT ) 407ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 408ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* make up vertical ones */ 409ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov metrics->vertAdvance = ( face->type1.font_bbox.yMax - 410ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov face->type1.font_bbox.yMin ) >> 16; 411ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov t1glyph->linearVertAdvance = metrics->vertAdvance; 412ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 413ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov else 414ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 415ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov metrics->vertAdvance = 416ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FIXED_TO_INT( decoder.builder.advance.y ); 417ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov t1glyph->linearVertAdvance = 418ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FIXED_TO_INT( decoder.builder.advance.y ); 419ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 420ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 421ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov t1glyph->format = FT_GLYPH_FORMAT_OUTLINE; 422ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 423ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( t1size && t1size->metrics.y_ppem < 24 ) 424ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov t1glyph->outline.flags |= FT_OUTLINE_HIGH_PRECISION; 425ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 426ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov#if 1 427ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* apply the font matrix, if any */ 428ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( font_matrix.xx != 0x10000L || font_matrix.yy != font_matrix.xx || 429ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov font_matrix.xy != 0 || font_matrix.yx != 0 ) 430ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_Outline_Transform( &t1glyph->outline, &font_matrix ); 431ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 432ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( font_offset.x || font_offset.y ) 433ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_Outline_Translate( &t1glyph->outline, 434ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov font_offset.x, 435ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov font_offset.y ); 436ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 437ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov advance.x = metrics->horiAdvance; 438ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov advance.y = 0; 439ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_Vector_Transform( &advance, &font_matrix ); 440ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov metrics->horiAdvance = advance.x + font_offset.x; 441ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov advance.x = 0; 442ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov advance.y = metrics->vertAdvance; 443ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_Vector_Transform( &advance, &font_matrix ); 444ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov metrics->vertAdvance = advance.y + font_offset.y; 445ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov#endif 446ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 447ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( ( load_flags & FT_LOAD_NO_SCALE ) == 0 ) 448ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 449ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* scale the outline and the metrics */ 450ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_Int n; 451ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_Outline* cur = decoder.builder.base; 452ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_Vector* vec = cur->points; 453ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_Fixed x_scale = glyph->x_scale; 454ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_Fixed y_scale = glyph->y_scale; 455ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 456ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 457ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* First of all, scale the points, if we are not hinting */ 458ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( !hinting || ! decoder.builder.hints_funcs ) 459ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov for ( n = cur->n_points; n > 0; n--, vec++ ) 460ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 461ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov vec->x = FT_MulFix( vec->x, x_scale ); 462ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov vec->y = FT_MulFix( vec->y, y_scale ); 463ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 464ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 465ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* Then scale the metrics */ 466ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov metrics->horiAdvance = FT_MulFix( metrics->horiAdvance, x_scale ); 467ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov metrics->vertAdvance = FT_MulFix( metrics->vertAdvance, y_scale ); 468ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 469ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 470ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* compute the other metrics */ 471ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_Outline_Get_CBox( &t1glyph->outline, &cbox ); 472ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 473ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov metrics->width = cbox.xMax - cbox.xMin; 474ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov metrics->height = cbox.yMax - cbox.yMin; 475ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 476ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov metrics->horiBearingX = cbox.xMin; 477ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov metrics->horiBearingY = cbox.yMax; 478ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 479ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( load_flags & FT_LOAD_VERTICAL_LAYOUT ) 480ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 481ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* make up vertical ones */ 482ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov ft_synthesize_vertical_metrics( metrics, 483ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov metrics->vertAdvance ); 484ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 485ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 486ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 487ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* Set control data to the glyph charstrings. Note that this is */ 488ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* _not_ zero-terminated. */ 489ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov t1glyph->control_data = (FT_Byte*)glyph_data.pointer; 490ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov t1glyph->control_len = glyph_data.length; 491ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 492ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 493ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 494ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov Exit: 495ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 496ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov#ifdef FT_CONFIG_OPTION_INCREMENTAL 497ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( glyph_data_loaded && face->root.internal->incremental_interface ) 498ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 499ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov face->root.internal->incremental_interface->funcs->free_glyph_data( 500ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov face->root.internal->incremental_interface->object, 501ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov &glyph_data ); 502ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 503ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* Set the control data to null - it is no longer available if */ 504ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* loaded incrementally. */ 505ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov t1glyph->control_data = 0; 506ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov t1glyph->control_len = 0; 507ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 508ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov#endif 509ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 510ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( must_finish_decoder ) 511ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov decoder_funcs->done( &decoder ); 512ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 513ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov return error; 514ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 515ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 516ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 517ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov/* END */ 518