From ed7f62aca5eab9d808daf0879607779bd2670173 Mon Sep 17 00:00:00 2001 From: David Turner Date: Tue, 28 Mar 2000 11:19:28 +0000 Subject: [PATCH] support for FT_LOAD_NO_RECURSE needed by the auto-hinter --- src/truetype/ttgload.c | 118 +++++++++-------- src/type1/t1gload.c | 279 +++++++++++++++++++++++++---------------- src/type1/t1gload.h | 1 + src/type1z/t1gload.c | 259 +++++++++++++++++++++++--------------- src/type1z/t1gload.h | 1 + 5 files changed, 393 insertions(+), 265 deletions(-) diff --git a/src/truetype/ttgload.c b/src/truetype/ttgload.c index 33ac135a5..6c3b93fc2 100644 --- a/src/truetype/ttgload.c +++ b/src/truetype/ttgload.c @@ -474,7 +474,7 @@ TT_ULong ins_offset; /* check glyph index */ - index = (TT_UInt)glyph_index; + index = glyph_index; if ( index >= (TT_UInt)face->root.num_glyphs ) { error = TT_Err_Invalid_Glyph_Index; @@ -698,9 +698,39 @@ /* composite instructions, if we find some .. */ /* we will process them later.. */ ins_offset = FILE_Pos() + stream->cursor - stream->limit; - FORGET_Frame(); } #endif + FORGET_Frame(); + + /* if the flag FT_LOAD_NO_RECURSE is set, we return the subglyph */ + /* "as is" in the glyph slot (the client application will be */ + /* responsible for interpreting this data..) */ + if ( loader->load_flags & FT_LOAD_NO_RECURSE ) + { + FT_GlyphSlot glyph = loader->glyph; + + /* reallocate subglyph array if necessary */ + if (glyph->max_subglyphs < num_subglyphs) + { + FT_Memory memory = loader->face->root.memory; + + if ( REALLOC_ARRAY( glyph->subglyphs, glyph->max_subglyphs, + num_subglyphs, FT_SubGlyph ) ) + goto Fail; + + glyph->max_subglyphs = num_subglyphs; + } + + /* copy subglyph array */ + MEM_Copy( glyph->subglyphs, subglyphs, + num_subglyphs*sizeof(FT_SubGlyph)); + + /* set up remaining glyph fields */ + glyph->num_subglyphs = num_subglyphs; + glyph->format = ft_glyph_format_composite; + goto Load_End; + } + /*************************************************************************/ /*************************************************************************/ @@ -954,6 +984,7 @@ y_scale = size->root.metrics.y_scale; } + if ( glyph->format != ft_glyph_format_composite ) { TT_UInt u; for ( u = 0; u < num_points + 2; u++ ) @@ -964,30 +995,31 @@ for ( u = 0; u < num_contours; u++ ) glyph->outline.contours[u] = loader->base.contours[u]; + + /* glyph->outline.second_pass = TRUE; */ + glyph->outline.flags &= ~ft_outline_single_pass; + glyph->outline.n_points = num_points; + glyph->outline.n_contours = num_contours; + + /* translate array so that (0,0) is the glyph's origin */ + translate_array( (TT_UShort)(num_points + 2), + glyph->outline.points, + -loader->pp1.x, + 0 ); + + FT_Outline_Get_CBox( &glyph->outline, &bbox ); + + if ( IS_HINTED(loader->load_flags) ) + { + /* grid-fit the bounding box */ + bbox.xMin &= -64; + bbox.yMin &= -64; + bbox.xMax = (bbox.xMax + 63) & -64; + bbox.yMax = (bbox.yMax + 63) & -64; + } } - - glyph->outline.n_points = num_points; - glyph->outline.n_contours = num_contours; - - /* glyph->outline.second_pass = TRUE; */ - glyph->outline.flags &= ~ft_outline_single_pass; - - /* translate array so that (0,0) is the glyph's origin */ - translate_array( (TT_UShort)(num_points + 2), - glyph->outline.points, - -loader->pp1.x, - 0 ); - - FT_Outline_Get_CBox( &glyph->outline, &bbox ); - - if ( IS_HINTED(loader->load_flags) ) - { - /* grid-fit the bounding box */ - bbox.xMin &= -64; - bbox.yMin &= -64; - bbox.xMax = (bbox.xMax + 63) & -64; - bbox.yMax = (bbox.yMax + 63) & -64; - } + else + bbox = loader->bbox; /* get the device-independent scaled horizontal metrics */ /* take care of fixed-pitch fonts... */ @@ -1141,7 +1173,6 @@ glyph->metrics.width = bbox.xMax - bbox.xMin; glyph->metrics.height = bbox.yMax - bbox.yMin; - glyph->format = ft_glyph_format_outline; } @@ -1174,8 +1205,9 @@ stream = face->root.stream; memory = face->root.memory; error = 0; - - if ( !size || (load_flags & FT_LOAD_NO_SCALE) ) + + if ( !size || (load_flags & FT_LOAD_NO_SCALE) || + (load_flags & FT_LOAD_NO_RECURSE )) { size = NULL; load_flags |= FT_LOAD_NO_SCALE | @@ -1183,6 +1215,8 @@ FT_LOAD_NO_BITMAP; } + glyph->num_subglyphs = 0; + #ifdef TT_CONFIG_OPTION_EMBEDDED_BITMAPS /*********************************************************************/ /* Try to load embedded bitmap if any */ @@ -1245,6 +1279,9 @@ goto Exit; } loader.base = *zone; + + loader.zone.n_points = 0; + loader.zone.n_contours = 0; #ifdef TT_CONFIG_OPTION_BYTECODE_INTERPRETER if ( size ) @@ -1289,6 +1326,7 @@ #endif /* Main loading loop */ + glyph->format = ft_glyph_format_outline; error = load_truetype_glyph( &loader, glyph_index ); if (!error) compute_glyph_metrics( &loader, glyph_index ); @@ -1304,28 +1342,4 @@ - - - - - - - - - - - - - - - - - - - - - - - - /* END */ diff --git a/src/type1/t1gload.c b/src/type1/t1gload.c index 558ab6afb..26ff2f5b6 100644 --- a/src/type1/t1gload.c +++ b/src/type1/t1gload.c @@ -255,7 +255,7 @@ cur->n_points = 0; cur->n_contours = 0; cur->points = base->points + base->n_points; - cur->tags = base->tags + base->n_points; + cur->tags = base->tags + base->n_points; cur->contours = base->contours + base->n_contours; error = T1_Parse_CharStrings( decoder, @@ -268,48 +268,88 @@ n_base_points = cur->n_points; - /* save the left bearing and width of the base character */ - /* as they will be erased by the next load.. */ - left_bearing = decoder->builder.left_bearing; - advance = decoder->builder.advance; - - decoder->builder.left_bearing.x = 0; - decoder->builder.left_bearing.y = 0; - - /* Now load "achar" on top of */ - /* the base outline */ - /* */ - cur->n_points = 0; - cur->n_contours = 0; - cur->points = base->points + base->n_points; - cur->tags = base->tags + base->n_points; - cur->contours = base->contours + base->n_contours; - - error = T1_Parse_CharStrings( decoder, - type1->charstrings [achar_index], - type1->charstrings_len[achar_index], - type1->num_subrs, - type1->subrs, - type1->subrs_len ); - if (error) return error; - - /* adjust contours in accented character outline */ + if ( decoder->builder.no_recurse ) { - T1_Int n; + /* if we're trying to load a composite glyph, do not load the */ + /* accent character and return the array of subglyphs.. */ + FT_GlyphSlot glyph = (FT_GlyphSlot)decoder->builder.glyph; + FT_SubGlyph* subg; - for ( n = 0; n < cur->n_contours; n++ ) - cur->contours[n] += n_base_points; + /* reallocate subglyph array if necessary */ + if (glyph->max_subglyphs < 2) + { + FT_Memory memory = decoder->builder.face->root.memory; + + if ( REALLOC_ARRAY( glyph->subglyphs, glyph->max_subglyphs, + 2, FT_SubGlyph ) ) + return error; + + glyph->max_subglyphs = 2; + } + + subg = glyph->subglyphs; + + /* subglyph 0 = base character */ + subg->index = bchar_index; + subg->flags = FT_SUBGLYPH_FLAG_ARGS_ARE_XY_VALUES | + FT_SUBGLYPH_FLAG_USE_MY_METRICS; + subg->arg1 = 0; + subg->arg2 = 0; + subg++; + + /* subglyph 1 = accent character */ + subg->index = achar_index; + subg->flags = FT_SUBGLYPH_FLAG_ARGS_ARE_XY_VALUES; + subg->arg1 = adx - asb; + subg->arg2 = ady; + + /* set up remaining glyph fields */ + glyph->num_subglyphs = 2; + glyph->format = ft_glyph_format_composite; + } + else + { + /* save the left bearing and width of the base character */ + /* as they will be erased by the next load.. */ + left_bearing = decoder->builder.left_bearing; + advance = decoder->builder.advance; + + decoder->builder.left_bearing.x = 0; + decoder->builder.left_bearing.y = 0; + + /* Now load "achar" on top of */ + /* the base outline */ + /* */ + cur->n_points = 0; + cur->n_contours = 0; + cur->points = base->points + base->n_points; + cur->tags = base->tags + base->n_points; + cur->contours = base->contours + base->n_contours; + + error = T1_Parse_CharStrings( decoder, + type1->charstrings [achar_index], + type1->charstrings_len[achar_index], + type1->num_subrs, + type1->subrs, + type1->subrs_len ); + if (error) return error; + + /* adjust contours in accented character outline */ + { + T1_Int n; + + for ( n = 0; n < cur->n_contours; n++ ) + cur->contours[n] += n_base_points; + } + + /* restore the left side bearing and */ + /* advance width of the base character */ + decoder->builder.left_bearing = left_bearing; + decoder->builder.advance = advance; + + /* Finally, move the accent */ + FT_Outline_Translate( cur, adx - asb, ady ); } - - /* restore the left side bearing and */ - /* advance width of the base character */ - decoder->builder.left_bearing = left_bearing; - decoder->builder.advance = advance; - - /* Finally, move the accent */ - FT_Outline_Translate( cur, adx - asb, ady ); - - (void)asb; /* ignore this parameter */ return T1_Err_Ok; } @@ -1416,6 +1456,9 @@ T1_Bool hinting; T1_Font* type1 = &face->type1; + if (load_flags & FT_LOAD_NO_RECURSE) + load_flags |= FT_LOAD_NO_SCALE | FT_LOAD_NO_HINTING; + glyph->x_scale = size->root.metrics.x_scale; glyph->y_scale = size->root.metrics.y_scale; @@ -1470,6 +1513,7 @@ &gload_builder_interface ); decoder.builder.pass = 1; + decoder.builder.no_recurse = 0; error = T1_Parse_CharStrings( &decoder, type1->charstrings [glyph_index], @@ -1483,12 +1527,15 @@ } else #endif + { T1_Init_Decoder( &decoder, &gload_hinter_interface ); T1_Init_Builder( &decoder.builder, face, size, glyph, &gload_builder_interface ); + decoder.builder.no_recurse = !!(load_flags & FT_LOAD_NO_RECURSE); + /* now load the unscaled outline */ error = T1_Parse_CharStrings( &decoder, type1->charstrings [glyph_index], @@ -1507,82 +1554,92 @@ /* bearing the yMax.. */ if (!error) { - FT_BBox cbox; - FT_Glyph_Metrics* metrics = &glyph->root.metrics; - - FT_Outline_Get_CBox( &glyph->root.outline, &cbox ); - - /* grid fit the bounding box if necessary */ - if (hinting) + /* for composite glyphs, return only the left side bearing and the */ + /* advance width.. */ + if ( load_flags & FT_LOAD_NO_RECURSE ) { - cbox.xMin &= -64; - cbox.yMin &= -64; - cbox.xMax = ( cbox.xMax+63 ) & -64; - cbox.yMax = ( cbox.yMax+63 ) & -64; + glyph->root.metrics.horiBearingX = decoder.builder.left_bearing.x; + glyph->root.metrics.horiAdvance = decoder.builder.advance.x; } - - metrics->width = cbox.xMax - cbox.xMin; - metrics->height = cbox.yMax - cbox.yMin; - - metrics->horiBearingX = cbox.xMin; - metrics->horiBearingY = cbox.yMax; - - /* copy the _unscaled_ advance width */ - metrics->horiAdvance = decoder.builder.advance.x; - - /* make up vertical metrics */ - metrics->vertBearingX = 0; - metrics->vertBearingY = 0; - metrics->vertAdvance = 0; - - glyph->root.format = ft_glyph_format_outline; - - glyph->root.outline.flags &= ft_outline_owner; - - if ( size->root.metrics.y_ppem < 24 ) - glyph->root.outline.flags |= ft_outline_high_precision; - - /* - glyph->root.outline.second_pass = TRUE; - glyph->root.outline.high_precision = ( size->root.metrics.y_ppem < 24 ); - glyph->root.outline.dropout_mode = 2; - */ - - if ( hinting ) + else { - /* adjust the advance width */ - /* XXX : TODO : consider stem hints grid-fit */ - metrics->horiAdvance = FT_MulFix( metrics->horiAdvance, - glyph->x_scale ); - } - else if ( (load_flags & FT_LOAD_NO_SCALE) == 0 ) - { - /* scale the outline and the metrics */ - T1_Int n; - FT_Outline* cur = &decoder.builder.base; - T1_Vector* vec = cur->points; - T1_Fixed x_scale = glyph->x_scale; - T1_Fixed y_scale = glyph->y_scale; - - /* First of all, scale the points */ - for ( n = cur->n_points; n > 0; n--, vec++ ) + FT_BBox cbox; + FT_Glyph_Metrics* metrics = &glyph->root.metrics; + + FT_Outline_Get_CBox( &glyph->root.outline, &cbox ); + + /* grid fit the bounding box if necessary */ + if (hinting) { - vec->x = FT_MulFix( vec->x, x_scale ); - vec->y = FT_MulFix( vec->y, y_scale ); + cbox.xMin &= -64; + cbox.yMin &= -64; + cbox.xMax = ( cbox.xMax+63 ) & -64; + cbox.yMax = ( cbox.yMax+63 ) & -64; + } + + metrics->width = cbox.xMax - cbox.xMin; + metrics->height = cbox.yMax - cbox.yMin; + + metrics->horiBearingX = cbox.xMin; + metrics->horiBearingY = cbox.yMax; + + /* copy the _unscaled_ advance width */ + metrics->horiAdvance = decoder.builder.advance.x; + + /* make up vertical metrics */ + metrics->vertBearingX = 0; + metrics->vertBearingY = 0; + metrics->vertAdvance = 0; + + glyph->root.format = ft_glyph_format_outline; + + glyph->root.outline.flags &= ft_outline_owner; + + if ( size->root.metrics.y_ppem < 24 ) + glyph->root.outline.flags |= ft_outline_high_precision; + + /* + glyph->root.outline.second_pass = TRUE; + glyph->root.outline.high_precision = ( size->root.metrics.y_ppem < 24 ); + glyph->root.outline.dropout_mode = 2; + */ + + if ( hinting ) + { + /* adjust the advance width */ + /* XXX : TODO : consider stem hints grid-fit */ + metrics->horiAdvance = FT_MulFix( metrics->horiAdvance, + glyph->x_scale ); + } + else if ( (load_flags & FT_LOAD_NO_SCALE) == 0 ) + { + /* scale the outline and the metrics */ + T1_Int n; + FT_Outline* cur = &decoder.builder.base; + T1_Vector* vec = cur->points; + T1_Fixed x_scale = glyph->x_scale; + T1_Fixed y_scale = glyph->y_scale; + + /* First of all, scale the points */ + for ( n = cur->n_points; n > 0; n--, vec++ ) + { + vec->x = FT_MulFix( vec->x, x_scale ); + vec->y = FT_MulFix( vec->y, y_scale ); + } + + /* Then scale the metrics */ + metrics->width = FT_MulFix( metrics->width, x_scale ); + metrics->height = FT_MulFix( metrics->height, y_scale ); + + metrics->horiBearingX = FT_MulFix( metrics->horiBearingX, x_scale ); + metrics->horiBearingY = FT_MulFix( metrics->horiBearingY, y_scale ); + metrics->horiAdvance = FT_MulFix( metrics->horiAdvance, x_scale ); + + metrics->vertBearingX = FT_MulFix( metrics->vertBearingX, x_scale ); + metrics->vertBearingY = FT_MulFix( metrics->vertBearingY, y_scale ); + metrics->vertAdvance = FT_MulFix( metrics->vertAdvance, x_scale ); + } - - /* Then scale the metrics */ - metrics->width = FT_MulFix( metrics->width, x_scale ); - metrics->height = FT_MulFix( metrics->height, y_scale ); - - metrics->horiBearingX = FT_MulFix( metrics->horiBearingX, x_scale ); - metrics->horiBearingY = FT_MulFix( metrics->horiBearingY, y_scale ); - metrics->horiAdvance = FT_MulFix( metrics->horiAdvance, x_scale ); - - metrics->vertBearingX = FT_MulFix( metrics->vertBearingX, x_scale ); - metrics->vertBearingY = FT_MulFix( metrics->vertBearingY, y_scale ); - metrics->vertAdvance = FT_MulFix( metrics->vertAdvance, x_scale ); - } } diff --git a/src/type1/t1gload.h b/src/type1/t1gload.h index f635b8197..6b42d7a8c 100644 --- a/src/type1/t1gload.h +++ b/src/type1/t1gload.h @@ -159,6 +159,7 @@ T1_Vector left_bearing; T1_Vector advance; + T1_Bool no_recurse; T1_BBox bbox; /* bounding box */ T1_Bool path_begun; diff --git a/src/type1z/t1gload.c b/src/type1z/t1gload.c index f152bba72..dccfe4fc5 100644 --- a/src/type1z/t1gload.c +++ b/src/type1z/t1gload.c @@ -475,50 +475,90 @@ n_base_points = cur->n_points; - /* save the left bearing and width of the base character */ - /* as they will be erase by the next load.. */ - left_bearing = decoder->builder.left_bearing; - advance = decoder->builder.advance; - - decoder->builder.left_bearing.x = 0; - decoder->builder.left_bearing.y = 0; - - /* Now load "achar" on top of */ - /* the base outline */ - /* */ - cur->n_points = 0; - cur->n_contours = 0; - cur->points = base->points + base->n_points; - cur->tags = base->tags + base->n_points; - cur->contours = base->contours + base->n_contours; - - error = T1_Parse_CharStrings( decoder, - type1->charstrings [achar_index], - type1->charstrings_len[achar_index], - type1->num_subrs, - type1->subrs, - type1->subrs_len ); - if (error) return error; - - /* adjust contours in accented character outline */ - if (decoder->builder.load_points) + if ( decoder->builder.no_recurse ) { - T1_Int n; + /* if we're trying to load a composite glyph, do not load the */ + /* accent character and return the array of subglyphs.. */ + FT_GlyphSlot glyph = (FT_GlyphSlot)decoder->builder.glyph; + FT_SubGlyph* subg; - for ( n = 0; n < cur->n_contours; n++ ) - cur->contours[n] += n_base_points; + /* reallocate subglyph array if necessary */ + if (glyph->max_subglyphs < 2) + { + FT_Memory memory = decoder->builder.face->root.memory; + + if ( REALLOC_ARRAY( glyph->subglyphs, glyph->max_subglyphs, + 2, FT_SubGlyph ) ) + return error; + + glyph->max_subglyphs = 2; + } + + subg = glyph->subglyphs; + + /* subglyph 0 = base character */ + subg->index = bchar_index; + subg->flags = FT_SUBGLYPH_FLAG_ARGS_ARE_XY_VALUES | + FT_SUBGLYPH_FLAG_USE_MY_METRICS; + subg->arg1 = 0; + subg->arg2 = 0; + subg++; + + /* subglyph 1 = accent character */ + subg->index = achar_index; + subg->flags = FT_SUBGLYPH_FLAG_ARGS_ARE_XY_VALUES; + subg->arg1 = adx - asb; + subg->arg2 = ady; + + /* set up remaining glyph fields */ + glyph->num_subglyphs = 2; + glyph->format = ft_glyph_format_composite; + } + else + { + /* save the left bearing and width of the base character */ + /* as they will be erase by the next load.. */ + left_bearing = decoder->builder.left_bearing; + advance = decoder->builder.advance; + + decoder->builder.left_bearing.x = 0; + decoder->builder.left_bearing.y = 0; + + /* Now load "achar" on top of */ + /* the base outline */ + /* */ + cur->n_points = 0; + cur->n_contours = 0; + cur->points = base->points + base->n_points; + cur->tags = base->tags + base->n_points; + cur->contours = base->contours + base->n_contours; + + error = T1_Parse_CharStrings( decoder, + type1->charstrings [achar_index], + type1->charstrings_len[achar_index], + type1->num_subrs, + type1->subrs, + type1->subrs_len ); + if (error) return error; + + /* adjust contours in accented character outline */ + if (decoder->builder.load_points) + { + T1_Int n; + + for ( n = 0; n < cur->n_contours; n++ ) + cur->contours[n] += n_base_points; + } + + /* restore the left side bearing and */ + /* advance width of the base character */ + decoder->builder.left_bearing = left_bearing; + decoder->builder.advance = advance; + + /* Finally, move the accent */ + if (decoder->builder.load_points) + FT_Outline_Translate( cur, adx - asb, ady ); } - - /* restore the left side bearing and */ - /* advance width of the base character */ - decoder->builder.left_bearing = left_bearing; - decoder->builder.advance = advance; - - /* Finally, move the accent */ - if (decoder->builder.load_points) - FT_Outline_Translate( cur, adx - asb, ady ); - - (void)asb; /* ignore this parameter */ return T1_Err_Ok; } @@ -1213,6 +1253,9 @@ T1_Bool hinting; T1_Font* type1 = &face->type1; + if (load_flags & FT_LOAD_NO_RECURSE) + load_flags |= FT_LOAD_NO_SCALE | FT_LOAD_NO_HINTING; + glyph->x_scale = size->root.metrics.x_scale; glyph->y_scale = size->root.metrics.y_scale; @@ -1228,6 +1271,8 @@ T1_Init_Decoder( &decoder ); T1_Init_Builder( &decoder.builder, face, size, glyph ); + decoder.builder.no_recurse = !!(load_flags & FT_LOAD_NO_RECURSE); + /* now load the unscaled outline */ error = T1_Parse_CharStrings( &decoder, type1->charstrings [glyph_index], @@ -1245,72 +1290,82 @@ /* bearing the yMax.. */ if (!error) { - FT_BBox cbox; - FT_Glyph_Metrics* metrics = &glyph->root.metrics; - - FT_Outline_Get_CBox( &glyph->root.outline, &cbox ); - - /* grid fit the bounding box if necessary */ - if (hinting) + /* for composite glyphs, return only the left side bearing and the */ + /* advance width.. */ + if ( load_flags & FT_LOAD_NO_RECURSE ) { - cbox.xMin &= -64; - cbox.yMin &= -64; - cbox.xMax = ( cbox.xMax+63 ) & -64; - cbox.yMax = ( cbox.yMax+63 ) & -64; + glyph->root.metrics.horiBearingX = decoder.builder.left_bearing.x; + glyph->root.metrics.horiAdvance = decoder.builder.advance.x; } - - metrics->width = cbox.xMax - cbox.xMin; - metrics->height = cbox.yMax - cbox.yMin; - - metrics->horiBearingX = cbox.xMin; - metrics->horiBearingY = cbox.yMax; - - /* copy the _unscaled_ advance width */ - metrics->horiAdvance = decoder.builder.advance.x; - - /* make up vertical metrics */ - metrics->vertBearingX = 0; - metrics->vertBearingY = 0; - metrics->vertAdvance = 0; - - glyph->root.format = ft_glyph_format_outline; - - glyph->root.outline.flags &= ft_outline_owner; - if ( size->root.metrics.y_ppem < 24 ) - glyph->root.outline.flags |= ft_outline_high_precision; - /* - glyph->root.outline.second_pass = TRUE; - glyph->root.outline.high_precision = ( size->root.metrics.y_ppem < 24 ); - glyph->root.outline.dropout_mode = 2; - */ - - if ( (load_flags & FT_LOAD_NO_SCALE) == 0 ) + else { - /* scale the outline and the metrics */ - T1_Int n; - FT_Outline* cur = &decoder.builder.base; - T1_Vector* vec = cur->points; - T1_Fixed x_scale = glyph->x_scale; - T1_Fixed y_scale = glyph->y_scale; - - /* First of all, scale the points */ - for ( n = cur->n_points; n > 0; n--, vec++ ) + FT_BBox cbox; + FT_Glyph_Metrics* metrics = &glyph->root.metrics; + + FT_Outline_Get_CBox( &glyph->root.outline, &cbox ); + + /* grid fit the bounding box if necessary */ + if (hinting) { - vec->x = FT_MulFix( vec->x, x_scale ); - vec->y = FT_MulFix( vec->y, y_scale ); + cbox.xMin &= -64; + cbox.yMin &= -64; + cbox.xMax = ( cbox.xMax+63 ) & -64; + cbox.yMax = ( cbox.yMax+63 ) & -64; + } + + metrics->width = cbox.xMax - cbox.xMin; + metrics->height = cbox.yMax - cbox.yMin; + + metrics->horiBearingX = cbox.xMin; + metrics->horiBearingY = cbox.yMax; + + /* copy the _unscaled_ advance width */ + metrics->horiAdvance = decoder.builder.advance.x; + + /* make up vertical metrics */ + metrics->vertBearingX = 0; + metrics->vertBearingY = 0; + metrics->vertAdvance = 0; + + glyph->root.format = ft_glyph_format_outline; + + glyph->root.outline.flags &= ft_outline_owner; + if ( size->root.metrics.y_ppem < 24 ) + glyph->root.outline.flags |= ft_outline_high_precision; + /* + glyph->root.outline.second_pass = TRUE; + glyph->root.outline.high_precision = ( size->root.metrics.y_ppem < 24 ); + glyph->root.outline.dropout_mode = 2; + */ + + if ( (load_flags & FT_LOAD_NO_SCALE) == 0 ) + { + /* scale the outline and the metrics */ + T1_Int n; + FT_Outline* cur = &decoder.builder.base; + T1_Vector* vec = cur->points; + T1_Fixed x_scale = glyph->x_scale; + T1_Fixed y_scale = glyph->y_scale; + + /* First of all, scale the points */ + for ( n = cur->n_points; n > 0; n--, vec++ ) + { + vec->x = FT_MulFix( vec->x, x_scale ); + vec->y = FT_MulFix( vec->y, y_scale ); + } + + /* Then scale the metrics */ + metrics->width = FT_MulFix( metrics->width, x_scale ); + metrics->height = FT_MulFix( metrics->height, y_scale ); + + metrics->horiBearingX = FT_MulFix( metrics->horiBearingX, x_scale ); + metrics->horiBearingY = FT_MulFix( metrics->horiBearingY, y_scale ); + metrics->horiAdvance = FT_MulFix( metrics->horiAdvance, x_scale ); + + metrics->vertBearingX = FT_MulFix( metrics->vertBearingX, x_scale ); + metrics->vertBearingY = FT_MulFix( metrics->vertBearingY, y_scale ); + metrics->vertAdvance = FT_MulFix( metrics->vertAdvance, x_scale ); } - - /* Then scale the metrics */ - metrics->width = FT_MulFix( metrics->width, x_scale ); - metrics->height = FT_MulFix( metrics->height, y_scale ); - - metrics->horiBearingX = FT_MulFix( metrics->horiBearingX, x_scale ); - metrics->horiBearingY = FT_MulFix( metrics->horiBearingY, y_scale ); - metrics->horiAdvance = FT_MulFix( metrics->horiAdvance, x_scale ); - - metrics->vertBearingX = FT_MulFix( metrics->vertBearingX, x_scale ); - metrics->vertBearingY = FT_MulFix( metrics->vertBearingY, y_scale ); - metrics->vertAdvance = FT_MulFix( metrics->vertAdvance, x_scale ); } } return error; diff --git a/src/type1z/t1gload.h b/src/type1z/t1gload.h index 0bf082f98..3c2de5ebb 100644 --- a/src/type1z/t1gload.h +++ b/src/type1z/t1gload.h @@ -107,6 +107,7 @@ T1_BBox bbox; /* bounding box */ T1_Bool path_begun; T1_Bool load_points; + T1_Bool no_recurse; T1_Error error; /* only used for memory errors */ T1_Bool metrics_only;