aboutsummaryrefslogtreecommitdiff
path: root/freetype/src/cff/cf2ft.c
diff options
context:
space:
mode:
authormarha <marha@users.sourceforge.net>2013-06-21 11:18:17 +0200
committermarha <marha@users.sourceforge.net>2013-06-21 11:18:17 +0200
commit039fb6c83783fff3b92f1e7934ce4702cedb1722 (patch)
treebb971ed2e247f7d311b696e62c7ed4d66b199b6d /freetype/src/cff/cf2ft.c
parent84f6a75a56f4749f91a51a161c1989cbc8807b80 (diff)
parentfa791414601df61d20d860299dba80fdb62565df (diff)
downloadvcxsrv-039fb6c83783fff3b92f1e7934ce4702cedb1722.tar.gz
vcxsrv-039fb6c83783fff3b92f1e7934ce4702cedb1722.tar.bz2
vcxsrv-039fb6c83783fff3b92f1e7934ce4702cedb1722.zip
Merge remote-tracking branch 'origin/released'
* origin/released: Upgraded freetype to 2.5.0.1 Conflicts: freetype/src/base/ftcalc.c freetype/src/base/ftgloadr.c freetype/src/base/ftgxval.c freetype/src/base/ftotval.c freetype/src/base/ftoutln.c freetype/src/base/ftpfr.c freetype/src/base/fttrigon.c freetype/src/cff/cffobjs.c freetype/src/psaux/afmparse.c freetype/src/psnames/psmodule.c freetype/src/raster/ftraster.c freetype/src/raster/ftrend1.c freetype/src/sfnt/ttsbit.c freetype/src/sfnt/ttsbit0.c freetype/src/truetype/ttobjs.c freetype/src/truetype/ttsubpix.c freetype/src/type1/t1afm.c
Diffstat (limited to 'freetype/src/cff/cf2ft.c')
-rw-r--r--freetype/src/cff/cf2ft.c639
1 files changed, 639 insertions, 0 deletions
diff --git a/freetype/src/cff/cf2ft.c b/freetype/src/cff/cf2ft.c
new file mode 100644
index 000000000..c09a0244a
--- /dev/null
+++ b/freetype/src/cff/cf2ft.c
@@ -0,0 +1,639 @@
+/***************************************************************************/
+/* */
+/* cf2ft.c */
+/* */
+/* FreeType Glue Component to Adobe's Interpreter (body). */
+/* */
+/* Copyright 2013 Adobe Systems Incorporated. */
+/* */
+/* This software, and all works of authorship, whether in source or */
+/* object code form as indicated by the copyright notice(s) included */
+/* herein (collectively, the "Work") is made available, and may only be */
+/* used, modified, and distributed under the FreeType Project License, */
+/* LICENSE.TXT. Additionally, subject to the terms and conditions of the */
+/* FreeType Project License, each contributor to the Work hereby grants */
+/* to any individual or legal entity exercising permissions granted by */
+/* the FreeType Project License and this section (hereafter, "You" or */
+/* "Your") a perpetual, worldwide, non-exclusive, no-charge, */
+/* royalty-free, irrevocable (except as stated in this section) patent */
+/* license to make, have made, use, offer to sell, sell, import, and */
+/* otherwise transfer the Work, where such license applies only to those */
+/* patent claims licensable by such contributor that are necessarily */
+/* infringed by their contribution(s) alone or by combination of their */
+/* contribution(s) with the Work to which such contribution(s) was */
+/* submitted. If You institute patent litigation against any entity */
+/* (including a cross-claim or counterclaim in a lawsuit) alleging that */
+/* the Work or a contribution incorporated within the Work constitutes */
+/* direct or contributory patent infringement, then any patent licenses */
+/* granted to You under this License for that Work shall terminate as of */
+/* the date such litigation is filed. */
+/* */
+/* By using, modifying, or distributing the Work you indicate that you */
+/* have read and understood the terms and conditions of the */
+/* FreeType Project License as well as those provided in this section, */
+/* and you accept them fully. */
+/* */
+/***************************************************************************/
+
+
+#include "cf2ft.h"
+#include FT_INTERNAL_DEBUG_H
+
+#include "cf2font.h"
+#include "cf2error.h"
+
+
+#define CF2_MAX_SIZE cf2_intToFixed( 2000 ) /* max ppem */
+
+
+ /*
+ * This check should avoid most internal overflow cases. Clients should
+ * generally respond to `Glyph_Too_Big' by getting a glyph outline
+ * at EM size, scaling it and filling it as a graphics operation.
+ *
+ */
+ static FT_Error
+ cf2_checkTransform( const CF2_Matrix* transform,
+ CF2_Int unitsPerEm )
+ {
+ CF2_Fixed maxScale;
+
+
+ FT_ASSERT( unitsPerEm > 0 );
+
+ FT_ASSERT( transform->a > 0 && transform->d > 0 );
+ FT_ASSERT( transform->b == 0 && transform->c == 0 );
+ FT_ASSERT( transform->tx == 0 && transform->ty == 0 );
+
+ if ( unitsPerEm > 0x7FFF )
+ return FT_THROW( Glyph_Too_Big );
+
+ maxScale = FT_DivFix( CF2_MAX_SIZE, cf2_intToFixed( unitsPerEm ) );
+
+ if ( transform->a > maxScale || transform->d > maxScale )
+ return FT_THROW( Glyph_Too_Big );
+
+ return FT_Err_Ok;
+ }
+
+
+ static void
+ cf2_setGlyphWidth( CF2_Outline outline,
+ CF2_Fixed width )
+ {
+ CFF_Decoder* decoder = outline->decoder;
+
+
+ FT_ASSERT( decoder );
+
+ decoder->glyph_width = cf2_fixedToInt( width );
+ }
+
+
+ /* Clean up font instance. */
+ static void
+ cf2_free_instance( void* ptr )
+ {
+ CF2_Font font = (CF2_Font)ptr;
+
+
+ if ( font )
+ {
+ FT_Memory memory = font->memory;
+
+
+ (void)memory;
+ }
+ }
+
+
+ /********************************************/
+ /* */
+ /* functions for handling client outline; */
+ /* FreeType uses coordinates in 26.6 format */
+ /* */
+ /********************************************/
+
+ static void
+ cf2_builder_moveTo( CF2_OutlineCallbacks callbacks,
+ const CF2_CallbackParams params )
+ {
+ /* downcast the object pointer */
+ CF2_Outline outline = (CF2_Outline)callbacks;
+ CFF_Builder* builder;
+
+ (void)params; /* only used in debug mode */
+
+
+ FT_ASSERT( outline && outline->decoder );
+ FT_ASSERT( params->op == CF2_PathOpMoveTo );
+
+ builder = &outline->decoder->builder;
+
+ /* note: two successive moves simply close the contour twice */
+ cff_builder_close_contour( builder );
+ builder->path_begun = 0;
+ }
+
+
+ static void
+ cf2_builder_lineTo( CF2_OutlineCallbacks callbacks,
+ const CF2_CallbackParams params )
+ {
+ /* downcast the object pointer */
+ CF2_Outline outline = (CF2_Outline)callbacks;
+ CFF_Builder* builder;
+
+
+ FT_ASSERT( outline && outline->decoder );
+ FT_ASSERT( params->op == CF2_PathOpLineTo );
+
+ builder = &outline->decoder->builder;
+
+ if ( !builder->path_begun )
+ {
+ /* record the move before the line; also check points and set */
+ /* `path_begun' */
+ cff_builder_start_point( builder,
+ params->pt0.x,
+ params->pt0.y );
+ }
+
+ /* `cff_builder_add_point1' includes a check_points call for one point */
+ cff_builder_add_point1( builder,
+ params->pt1.x,
+ params->pt1.y );
+ }
+
+
+ static void
+ cf2_builder_cubeTo( CF2_OutlineCallbacks callbacks,
+ const CF2_CallbackParams params )
+ {
+ /* downcast the object pointer */
+ CF2_Outline outline = (CF2_Outline)callbacks;
+ CFF_Builder* builder;
+
+
+ FT_ASSERT( outline && outline->decoder );
+ FT_ASSERT( params->op == CF2_PathOpCubeTo );
+
+ builder = &outline->decoder->builder;
+
+ if ( !builder->path_begun )
+ {
+ /* record the move before the line; also check points and set */
+ /* `path_begun' */
+ cff_builder_start_point( builder,
+ params->pt0.x,
+ params->pt0.y );
+ }
+
+ /* prepare room for 3 points: 2 off-curve, 1 on-curve */
+ cff_check_points( builder, 3 );
+
+ cff_builder_add_point( builder,
+ params->pt1.x,
+ params->pt1.y, 0 );
+ cff_builder_add_point( builder,
+ params->pt2.x,
+ params->pt2.y, 0 );
+ cff_builder_add_point( builder,
+ params->pt3.x,
+ params->pt3.y, 1 );
+ }
+
+
+ static void
+ cf2_outline_init( CF2_Outline outline,
+ FT_Memory memory,
+ FT_Error* error )
+ {
+ FT_MEM_ZERO( outline, sizeof ( CF2_OutlineRec ) );
+
+ outline->root.memory = memory;
+ outline->root.error = error;
+
+ outline->root.moveTo = cf2_builder_moveTo;
+ outline->root.lineTo = cf2_builder_lineTo;
+ outline->root.cubeTo = cf2_builder_cubeTo;
+ }
+
+
+ /* get scaling and hint flag from GlyphSlot */
+ static void
+ cf2_getScaleAndHintFlag( CFF_Decoder* decoder,
+ CF2_Fixed* x_scale,
+ CF2_Fixed* y_scale,
+ FT_Bool* hinted,
+ FT_Bool* scaled )
+ {
+ FT_ASSERT( decoder && decoder->builder.glyph );
+
+ /* note: FreeType scale includes a factor of 64 */
+ *hinted = decoder->builder.glyph->hint;
+ *scaled = decoder->builder.glyph->scaled;
+
+ if ( *hinted )
+ {
+ *x_scale = FT_DivFix( decoder->builder.glyph->x_scale,
+ cf2_intToFixed( 64 ) );
+ *y_scale = FT_DivFix( decoder->builder.glyph->y_scale,
+ cf2_intToFixed( 64 ) );
+ }
+ else
+ {
+ /* for unhinted outlines, `cff_slot_load' does the scaling, */
+ /* thus render at `unity' scale */
+
+ *x_scale = 0x0400; /* 1/64 as 16.16 */
+ *y_scale = 0x0400;
+ }
+ }
+
+
+ /* get units per em from `FT_Face' */
+ /* TODO: should handle font matrix concatenation? */
+ static FT_UShort
+ cf2_getUnitsPerEm( CFF_Decoder* decoder )
+ {
+ FT_ASSERT( decoder && decoder->builder.face );
+ FT_ASSERT( decoder->builder.face->root.units_per_EM );
+
+ return decoder->builder.face->root.units_per_EM;
+ }
+
+
+ /* Main entry point: Render one glyph. */
+ FT_LOCAL_DEF( FT_Error )
+ cf2_decoder_parse_charstrings( CFF_Decoder* decoder,
+ FT_Byte* charstring_base,
+ FT_ULong charstring_len )
+ {
+ FT_Memory memory;
+ FT_Error error = FT_Err_Ok;
+ CF2_Font font;
+
+
+ FT_ASSERT( decoder && decoder->cff );
+
+ memory = decoder->builder.memory;
+
+ /* CF2 data is saved here across glyphs */
+ font = (CF2_Font)decoder->cff->cf2_instance.data;
+
+ /* on first glyph, allocate instance structure */
+ if ( decoder->cff->cf2_instance.data == NULL )
+ {
+ decoder->cff->cf2_instance.finalizer =
+ (FT_Generic_Finalizer)cf2_free_instance;
+
+ if ( FT_ALLOC( decoder->cff->cf2_instance.data,
+ sizeof ( CF2_FontRec ) ) )
+ return FT_THROW( Out_Of_Memory );
+
+ font = (CF2_Font)decoder->cff->cf2_instance.data;
+
+ font->memory = memory;
+
+ /* initialize a client outline, to be shared by each glyph rendered */
+ cf2_outline_init( &font->outline, font->memory, &font->error );
+ }
+
+ /* save decoder; it is a stack variable and will be different on each */
+ /* call */
+ font->decoder = decoder;
+ font->outline.decoder = decoder;
+
+ {
+ /* build parameters for Adobe engine */
+
+ CFF_Builder* builder = &decoder->builder;
+ CFF_Driver driver = (CFF_Driver)FT_FACE_DRIVER( builder->face );
+
+ /* local error */
+ FT_Error error2 = FT_Err_Ok;
+ CF2_BufferRec buf;
+ CF2_Matrix transform;
+ CF2_F16Dot16 glyphWidth;
+
+ FT_Bool hinted;
+ FT_Bool scaled;
+
+
+ /* FreeType has already looked up the GID; convert to */
+ /* `RegionBuffer', assuming that the input has been validated */
+ FT_ASSERT( charstring_base + charstring_len >= charstring_base );
+
+ FT_ZERO( &buf );
+ buf.start =
+ buf.ptr = charstring_base;
+ buf.end = charstring_base + charstring_len;
+
+ FT_ZERO( &transform );
+
+ cf2_getScaleAndHintFlag( decoder,
+ &transform.a,
+ &transform.d,
+ &hinted,
+ &scaled );
+
+ font->renderingFlags = 0;
+ if ( hinted )
+ font->renderingFlags |= CF2_FlagsHinted;
+ if ( scaled && !driver->no_stem_darkening )
+ font->renderingFlags |= CF2_FlagsDarkened;
+
+ /* now get an outline for this glyph; */
+ /* also get units per em to validate scale */
+ font->unitsPerEm = (CF2_Int)cf2_getUnitsPerEm( decoder );
+
+ error2 = cf2_checkTransform( &transform, font->unitsPerEm );
+ if ( error2 )
+ return error2;
+
+ error2 = cf2_getGlyphOutline( font, &buf, &transform, &glyphWidth );
+ if ( error2 )
+ return FT_ERR( Invalid_File_Format );
+
+ cf2_setGlyphWidth( &font->outline, glyphWidth );
+
+ return FT_Err_Ok;
+ }
+ }
+
+
+ /* get pointer to current FreeType subfont (based on current glyphID) */
+ FT_LOCAL_DEF( CFF_SubFont )
+ cf2_getSubfont( CFF_Decoder* decoder )
+ {
+ FT_ASSERT( decoder && decoder->current_subfont );
+
+ return decoder->current_subfont;
+ }
+
+
+ /* get `y_ppem' from `CFF_Size' */
+ FT_LOCAL_DEF( CF2_Fixed )
+ cf2_getPpemY( CFF_Decoder* decoder )
+ {
+ FT_ASSERT( decoder &&
+ decoder->builder.face &&
+ decoder->builder.face->root.size );
+ FT_ASSERT( decoder->builder.face->root.size->metrics.y_ppem );
+
+ return cf2_intToFixed(
+ decoder->builder.face->root.size->metrics.y_ppem );
+ }
+
+
+ /* get standard stem widths for the current subfont; */
+ /* FreeType stores these as integer font units */
+ /* (note: variable names seem swapped) */
+ FT_LOCAL_DEF( CF2_Fixed )
+ cf2_getStdVW( CFF_Decoder* decoder )
+ {
+ FT_ASSERT( decoder && decoder->current_subfont );
+
+ return cf2_intToFixed(
+ decoder->current_subfont->private_dict.standard_height );
+ }
+
+
+ FT_LOCAL_DEF( CF2_Fixed )
+ cf2_getStdHW( CFF_Decoder* decoder )
+ {
+ FT_ASSERT( decoder && decoder->current_subfont );
+
+ return cf2_intToFixed(
+ decoder->current_subfont->private_dict.standard_width );
+ }
+
+
+ /* note: FreeType stores 1000 times the actual value for `BlueScale' */
+ FT_LOCAL_DEF( void )
+ cf2_getBlueMetrics( CFF_Decoder* decoder,
+ CF2_Fixed* blueScale,
+ CF2_Fixed* blueShift,
+ CF2_Fixed* blueFuzz )
+ {
+ FT_ASSERT( decoder && decoder->current_subfont );
+
+ *blueScale = FT_DivFix(
+ decoder->current_subfont->private_dict.blue_scale,
+ cf2_intToFixed( 1000 ) );
+ *blueShift = cf2_intToFixed(
+ decoder->current_subfont->private_dict.blue_shift );
+ *blueFuzz = cf2_intToFixed(
+ decoder->current_subfont->private_dict.blue_fuzz );
+ }
+
+
+ /* get blue values counts and arrays; the FreeType parser has validated */
+ /* the counts and verified that each is an even number */
+ FT_LOCAL_DEF( void )
+ cf2_getBlueValues( CFF_Decoder* decoder,
+ size_t* count,
+ FT_Pos* *data )
+ {
+ FT_ASSERT( decoder && decoder->current_subfont );
+
+ *count = decoder->current_subfont->private_dict.num_blue_values;
+ *data = (FT_Pos*)
+ &decoder->current_subfont->private_dict.blue_values;
+ }
+
+
+ FT_LOCAL_DEF( void )
+ cf2_getOtherBlues( CFF_Decoder* decoder,
+ size_t* count,
+ FT_Pos* *data )
+ {
+ FT_ASSERT( decoder && decoder->current_subfont );
+
+ *count = decoder->current_subfont->private_dict.num_other_blues;
+ *data = (FT_Pos*)
+ &decoder->current_subfont->private_dict.other_blues;
+ }
+
+
+ FT_LOCAL_DEF( void )
+ cf2_getFamilyBlues( CFF_Decoder* decoder,
+ size_t* count,
+ FT_Pos* *data )
+ {
+ FT_ASSERT( decoder && decoder->current_subfont );
+
+ *count = decoder->current_subfont->private_dict.num_family_blues;
+ *data = (FT_Pos*)
+ &decoder->current_subfont->private_dict.family_blues;
+ }
+
+
+ FT_LOCAL_DEF( void )
+ cf2_getFamilyOtherBlues( CFF_Decoder* decoder,
+ size_t* count,
+ FT_Pos* *data )
+ {
+ FT_ASSERT( decoder && decoder->current_subfont );
+
+ *count = decoder->current_subfont->private_dict.num_family_other_blues;
+ *data = (FT_Pos*)
+ &decoder->current_subfont->private_dict.family_other_blues;
+ }
+
+
+ FT_LOCAL_DEF( CF2_Int )
+ cf2_getLanguageGroup( CFF_Decoder* decoder )
+ {
+ FT_ASSERT( decoder && decoder->current_subfont );
+
+ return decoder->current_subfont->private_dict.language_group;
+ }
+
+
+ /* convert unbiased subroutine index to `CF2_Buffer' and */
+ /* return 0 on success */
+ FT_LOCAL_DEF( CF2_Int )
+ cf2_initGlobalRegionBuffer( CFF_Decoder* decoder,
+ CF2_UInt idx,
+ CF2_Buffer buf )
+ {
+ FT_ASSERT( decoder && decoder->globals );
+
+ FT_ZERO( buf );
+
+ idx += decoder->globals_bias;
+ if ( idx >= decoder->num_globals )
+ return TRUE; /* error */
+
+ buf->start =
+ buf->ptr = decoder->globals[idx];
+ buf->end = decoder->globals[idx + 1];
+
+ return FALSE; /* success */
+ }
+
+
+ /* convert AdobeStandardEncoding code to CF2_Buffer; */
+ /* used for seac component */
+ FT_LOCAL_DEF( FT_Error )
+ cf2_getSeacComponent( CFF_Decoder* decoder,
+ CF2_UInt code,
+ CF2_Buffer buf )
+ {
+ CF2_Int gid;
+ FT_Byte* charstring;
+ FT_ULong len;
+ FT_Error error;
+
+
+ FT_ASSERT( decoder );
+
+ FT_ZERO( buf );
+
+ gid = cff_lookup_glyph_by_stdcharcode( decoder->cff, code );
+ if ( gid < 0 )
+ return FT_THROW( Invalid_Glyph_Format );
+
+ error = cff_get_glyph_data( decoder->builder.face,
+ gid,
+ &charstring,
+ &len );
+ /* TODO: for now, just pass the FreeType error through */
+ if ( error )
+ return error;
+
+ /* assume input has been validated */
+ FT_ASSERT( charstring + len >= charstring );
+
+ buf->start = charstring;
+ buf->end = charstring + len;
+ buf->ptr = buf->start;
+
+ return FT_Err_Ok;
+ }
+
+
+ FT_LOCAL_DEF( void )
+ cf2_freeSeacComponent( CFF_Decoder* decoder,
+ CF2_Buffer buf )
+ {
+ FT_ASSERT( decoder );
+
+ cff_free_glyph_data( decoder->builder.face,
+ (FT_Byte**)&buf->start,
+ (FT_ULong)( buf->end - buf->start ) );
+ }
+
+
+ FT_LOCAL_DEF( CF2_Int )
+ cf2_initLocalRegionBuffer( CFF_Decoder* decoder,
+ CF2_UInt idx,
+ CF2_Buffer buf )
+ {
+ FT_ASSERT( decoder && decoder->locals );
+
+ FT_ZERO( buf );
+
+ idx += decoder->locals_bias;
+ if ( idx >= decoder->num_locals )
+ return TRUE; /* error */
+
+ buf->start =
+ buf->ptr = decoder->locals[idx];
+ buf->end = decoder->locals[idx + 1];
+
+ return FALSE; /* success */
+ }
+
+
+ FT_LOCAL_DEF( CF2_Fixed )
+ cf2_getDefaultWidthX( CFF_Decoder* decoder )
+ {
+ FT_ASSERT( decoder && decoder->current_subfont );
+
+ return cf2_intToFixed(
+ decoder->current_subfont->private_dict.default_width );
+ }
+
+
+ FT_LOCAL_DEF( CF2_Fixed )
+ cf2_getNominalWidthX( CFF_Decoder* decoder )
+ {
+ FT_ASSERT( decoder && decoder->current_subfont );
+
+ return cf2_intToFixed(
+ decoder->current_subfont->private_dict.nominal_width );
+ }
+
+
+ FT_LOCAL_DEF( void )
+ cf2_outline_reset( CF2_Outline outline )
+ {
+ CFF_Decoder* decoder = outline->decoder;
+
+
+ FT_ASSERT( decoder );
+
+ outline->root.windingMomentum = 0;
+
+ FT_GlyphLoader_Rewind( decoder->builder.loader );
+ }
+
+
+ FT_LOCAL_DEF( void )
+ cf2_outline_close( CF2_Outline outline )
+ {
+ CFF_Decoder* decoder = outline->decoder;
+
+
+ FT_ASSERT( decoder );
+
+ cff_builder_close_contour( &decoder->builder );
+
+ FT_GlyphLoader_Add( decoder->builder.loader );
+ }
+
+
+/* END */