diff options
Diffstat (limited to 'src/3rdparty/freetype/src/base/ftobjs.c')
-rw-r--r-- | src/3rdparty/freetype/src/base/ftobjs.c | 569 |
1 files changed, 444 insertions, 125 deletions
diff --git a/src/3rdparty/freetype/src/base/ftobjs.c b/src/3rdparty/freetype/src/base/ftobjs.c index e301f8f11a..eeda69c3ed 100644 --- a/src/3rdparty/freetype/src/base/ftobjs.c +++ b/src/3rdparty/freetype/src/base/ftobjs.c @@ -4,7 +4,7 @@ * * The FreeType private base classes (body). * - * Copyright (C) 1996-2019 by + * Copyright (C) 1996-2022 by * David Turner, Robert Wilhelm, and Werner Lemberg. * * This file is part of the FreeType project, and may only be used, @@ -16,32 +16,33 @@ */ -#include <ft2build.h> -#include FT_LIST_H -#include FT_OUTLINE_H -#include FT_FONT_FORMATS_H +#include <freetype/ftlist.h> +#include <freetype/ftoutln.h> +#include <freetype/ftfntfmt.h> +#include <freetype/otsvg.h> -#include FT_INTERNAL_VALIDATE_H -#include FT_INTERNAL_OBJECTS_H -#include FT_INTERNAL_DEBUG_H -#include FT_INTERNAL_RFORK_H -#include FT_INTERNAL_STREAM_H -#include FT_INTERNAL_SFNT_H /* for SFNT_Load_Table_Func */ -#include FT_INTERNAL_POSTSCRIPT_AUX_H /* for PS_Driver */ +#include <freetype/internal/ftvalid.h> +#include <freetype/internal/ftobjs.h> +#include <freetype/internal/ftdebug.h> +#include <freetype/internal/ftrfork.h> +#include <freetype/internal/ftstream.h> +#include <freetype/internal/sfnt.h> /* for SFNT_Load_Table_Func */ +#include <freetype/internal/psaux.h> /* for PS_Driver */ +#include <freetype/internal/svginterface.h> -#include FT_TRUETYPE_TABLES_H -#include FT_TRUETYPE_TAGS_H -#include FT_TRUETYPE_IDS_H +#include <freetype/tttables.h> +#include <freetype/tttags.h> +#include <freetype/ttnameid.h> -#include FT_SERVICE_PROPERTIES_H -#include FT_SERVICE_SFNT_H -#include FT_SERVICE_POSTSCRIPT_NAME_H -#include FT_SERVICE_GLYPH_DICT_H -#include FT_SERVICE_TT_CMAP_H -#include FT_SERVICE_KERNING_H -#include FT_SERVICE_TRUETYPE_ENGINE_H +#include <freetype/internal/services/svprop.h> +#include <freetype/internal/services/svsfnt.h> +#include <freetype/internal/services/svpostnm.h> +#include <freetype/internal/services/svgldict.h> +#include <freetype/internal/services/svttcmap.h> +#include <freetype/internal/services/svkern.h> +#include <freetype/internal/services/svtteng.h> -#include FT_DRIVER_H +#include <freetype/ftdriver.h> #ifdef FT_CONFIG_OPTION_MAC_FONTS #include "ftbase.h" @@ -50,7 +51,7 @@ #ifdef FT_DEBUG_LEVEL_TRACE -#include FT_BITMAP_H +#include <freetype/ftbitmap.h> #if defined( _MSC_VER ) /* Visual C++ (and Intel C++) */ /* We disable the warning `conversion from XXX to YYY, */ @@ -79,6 +80,9 @@ #pragma warning( pop ) #endif + /* This array must stay in sync with the @FT_Pixel_Mode enumeration */ + /* (in file `ftimage.h`). */ + static const char* const pixel_modes[] = { "none", @@ -88,7 +92,8 @@ "gray 4-bit bitmap", "LCD 8-bit bitmap", "vertical LCD 8-bit bitmap", - "BGRA 32-bit color image bitmap" + "BGRA 32-bit color image bitmap", + "SDF 8-bit bitmap" }; #endif /* FT_DEBUG_LEVEL_TRACE */ @@ -194,6 +199,7 @@ FT_Error error; FT_Memory memory; FT_Stream stream = NULL; + FT_UInt mode; *astream = NULL; @@ -205,49 +211,56 @@ return FT_THROW( Invalid_Argument ); memory = library->memory; + mode = args->flags & + ( FT_OPEN_MEMORY | FT_OPEN_STREAM | FT_OPEN_PATHNAME ); - if ( FT_NEW( stream ) ) - goto Exit; - - stream->memory = memory; - - if ( args->flags & FT_OPEN_MEMORY ) + if ( mode == FT_OPEN_MEMORY ) { /* create a memory-based stream */ + if ( FT_NEW( stream ) ) + goto Exit; + FT_Stream_OpenMemory( stream, (const FT_Byte*)args->memory_base, (FT_ULong)args->memory_size ); + stream->memory = memory; } #ifndef FT_CONFIG_OPTION_DISABLE_STREAM_SUPPORT - else if ( args->flags & FT_OPEN_PATHNAME ) + else if ( mode == FT_OPEN_PATHNAME ) { /* create a normal system stream */ + if ( FT_NEW( stream ) ) + goto Exit; + + stream->memory = memory; error = FT_Stream_Open( stream, args->pathname ); - stream->pathname.pointer = args->pathname; + if ( error ) + FT_FREE( stream ); } - else if ( ( args->flags & FT_OPEN_STREAM ) && args->stream ) + else if ( ( mode == FT_OPEN_STREAM ) && args->stream ) { /* use an existing, user-provided stream */ /* in this case, we do not need to allocate a new stream object */ /* since the caller is responsible for closing it himself */ - FT_FREE( stream ); - stream = args->stream; + stream = args->stream; + stream->memory = memory; + error = FT_Err_Ok; } #endif else + { error = FT_THROW( Invalid_Argument ); + if ( ( args->flags & FT_OPEN_STREAM ) && args->stream ) + FT_Stream_Close( args->stream ); + } - if ( error ) - FT_FREE( stream ); - else - stream->memory = memory; /* just to be certain */ - - *astream = stream; + if ( !error ) + *astream = stream; Exit: return error; @@ -317,6 +330,19 @@ if ( !error && clazz->init_slot ) error = clazz->init_slot( slot ); +#ifdef FT_CONFIG_OPTION_SVG + /* if SVG table exists, allocate the space in `slot->other` */ + if ( slot->face->face_flags & FT_FACE_FLAG_SVG ) + { + FT_SVG_Document document = NULL; + + + if ( FT_NEW( document ) ) + goto Exit; + slot->other = document; + } +#endif + Exit: return error; } @@ -361,7 +387,18 @@ FT_Pos width, height, pitch; - if ( slot->format != FT_GLYPH_FORMAT_OUTLINE ) + if ( slot->format == FT_GLYPH_FORMAT_SVG ) + { + FT_Module module; + SVG_Service svg_service; + + + module = FT_Get_Module( slot->library, "ot-svg" ); + svg_service = (SVG_Service)module->clazz->module_interface; + + return (FT_Bool)svg_service->preset_slot( module, slot, FALSE ); + } + else if ( slot->format != FT_GLYPH_FORMAT_OUTLINE ) return 1; if ( origin ) @@ -524,7 +561,7 @@ else slot->internal->flags |= FT_GLYPH_OWN_BITMAP; - (void)FT_ALLOC( slot->bitmap.buffer, size ); + FT_MEM_ALLOC( slot->bitmap.buffer, size ); return error; } @@ -536,6 +573,8 @@ ft_glyphslot_free_bitmap( slot ); /* clear all public fields in the glyph slot */ + slot->glyph_index = 0; + FT_ZERO( &slot->metrics ); FT_ZERO( &slot->outline ); @@ -551,11 +590,32 @@ slot->subglyphs = NULL; slot->control_data = NULL; slot->control_len = 0; - slot->other = NULL; - slot->format = FT_GLYPH_FORMAT_NONE; + +#ifndef FT_CONFIG_OPTION_SVG + slot->other = NULL; +#else + if ( !( slot->face->face_flags & FT_FACE_FLAG_SVG ) ) + slot->other = NULL; + else + { + if ( slot->internal->flags & FT_GLYPH_OWN_GZIP_SVG ) + { + FT_Memory memory = slot->face->memory; + FT_SVG_Document doc = (FT_SVG_Document)slot->other; + + + FT_FREE( doc->svg_document ); + slot->internal->load_flags &= ~FT_GLYPH_OWN_GZIP_SVG; + } + } +#endif + + slot->format = FT_GLYPH_FORMAT_NONE; slot->linearHoriAdvance = 0; slot->linearVertAdvance = 0; + slot->advance.x = 0; + slot->advance.y = 0; slot->lsb_delta = 0; slot->rsb_delta = 0; } @@ -568,6 +628,23 @@ FT_Driver_Class clazz = driver->clazz; FT_Memory memory = driver->root.memory; +#ifdef FT_CONFIG_OPTION_SVG + if ( slot->face->face_flags & FT_FACE_FLAG_SVG ) + { + /* free memory in case SVG was there */ + if ( slot->internal->flags & FT_GLYPH_OWN_GZIP_SVG ) + { + FT_SVG_Document doc = (FT_SVG_Document)slot->other; + + + FT_FREE( doc->svg_document ); + + slot->internal->flags &= ~FT_GLYPH_OWN_GZIP_SVG; + } + + FT_FREE( slot->other ); + } +#endif if ( clazz->done_slot ) clazz->done_slot( slot ); @@ -735,6 +812,29 @@ } + /* documentation is in freetype.h */ + + FT_EXPORT_DEF( void ) + FT_Get_Transform( FT_Face face, + FT_Matrix* matrix, + FT_Vector* delta ) + { + FT_Face_Internal internal; + + + if ( !face ) + return; + + internal = face->internal; + + if ( matrix ) + *matrix = internal->transform_matrix; + + if ( delta ) + *delta = internal->transform_delta; + } + + static FT_Renderer ft_lookup_glyph_renderer( FT_GlyphSlot slot ); @@ -820,6 +920,11 @@ library = driver->root.library; hinter = library->auto_hinter; + /* undefined scale means no scale */ + if ( face->size->metrics.x_ppem == 0 || + face->size->metrics.y_ppem == 0 ) + load_flags |= FT_LOAD_NO_SCALE; + /* resolve load flags dependencies */ if ( load_flags & FT_LOAD_NO_RECURSE ) @@ -909,11 +1014,21 @@ FT_AutoHinter_Interface hinting; - /* try to load embedded bitmaps first if available */ - /* */ - /* XXX: This is really a temporary hack that should disappear */ - /* promptly with FreeType 2.1! */ - /* */ + /* XXX: The use of the `FT_LOAD_XXX_ONLY` flags is not very */ + /* elegant. */ + + /* try to load SVG documents if available */ + if ( FT_HAS_SVG( face ) ) + { + error = driver->clazz->load_glyph( slot, face->size, + glyph_index, + load_flags | FT_LOAD_SVG_ONLY ); + + if ( !error && slot->format == FT_GLYPH_FORMAT_SVG ) + goto Load_Ok; + } + + /* try to load embedded bitmaps if available */ if ( FT_HAS_FIXED_SIZES( face ) && ( load_flags & FT_LOAD_NO_BITMAP ) == 0 ) { @@ -1057,17 +1172,41 @@ #ifdef FT_DEBUG_LEVEL_TRACE FT_TRACE5(( "FT_Load_Glyph: index %d, flags 0x%x\n", glyph_index, load_flags )); + FT_TRACE5(( " bitmap %dx%d %s, %s (mode %d)\n", + slot->bitmap.width, + slot->bitmap.rows, + slot->outline.points ? + slot->bitmap.buffer ? "rendered" + : "preset" + : + slot->internal->flags & FT_GLYPH_OWN_BITMAP ? "owned" + : "unowned", + pixel_modes[slot->bitmap.pixel_mode], + slot->bitmap.pixel_mode )); + FT_TRACE5(( "\n" )); FT_TRACE5(( " x advance: %f\n", slot->advance.x / 64.0 )); FT_TRACE5(( " y advance: %f\n", slot->advance.y / 64.0 )); FT_TRACE5(( " linear x advance: %f\n", slot->linearHoriAdvance / 65536.0 )); FT_TRACE5(( " linear y advance: %f\n", slot->linearVertAdvance / 65536.0 )); - FT_TRACE5(( " bitmap %dx%d, %s (mode %d)\n", - slot->bitmap.width, - slot->bitmap.rows, - pixel_modes[slot->bitmap.pixel_mode], - slot->bitmap.pixel_mode )); + + { + FT_Glyph_Metrics* metrics = &slot->metrics; + + + FT_TRACE5(( " metrics:\n" )); + FT_TRACE5(( " width: %f\n", metrics->width / 64.0 )); + FT_TRACE5(( " height: %f\n", metrics->height / 64.0 )); + FT_TRACE5(( "\n" )); + FT_TRACE5(( " horiBearingX: %f\n", metrics->horiBearingX / 64.0 )); + FT_TRACE5(( " horiBearingY: %f\n", metrics->horiBearingY / 64.0 )); + FT_TRACE5(( " horiAdvance: %f\n", metrics->horiAdvance / 64.0 )); + FT_TRACE5(( "\n" )); + FT_TRACE5(( " vertBearingX: %f\n", metrics->vertBearingX / 64.0 )); + FT_TRACE5(( " vertBearingY: %f\n", metrics->vertBearingY / 64.0 )); + FT_TRACE5(( " vertAdvance: %f\n", metrics->vertAdvance / 64.0 )); + } #endif Exit: @@ -1535,7 +1674,6 @@ FT_FREE( stream->base ); stream->size = 0; - stream->base = NULL; stream->close = NULL; } @@ -1764,7 +1902,7 @@ if ( error ) goto Exit; - if ( FT_ALLOC( sfnt_ps, (FT_Long)length ) ) + if ( FT_QALLOC( sfnt_ps, (FT_Long)length ) ) goto Exit; error = FT_Stream_Read( stream, (FT_Byte *)sfnt_ps, length ); @@ -1842,15 +1980,15 @@ /* FT2 allocator takes signed long buffer length, * too large value causing overflow should be checked */ - FT_TRACE4(( " POST fragment #%d: length=0x%08x" - " total pfb_len=0x%08x\n", + FT_TRACE4(( " POST fragment #%d: length=0x%08lx" + " total pfb_len=0x%08lx\n", i, temp, pfb_len + temp + 6 )); if ( FT_MAC_RFORK_MAX_LEN < temp || FT_MAC_RFORK_MAX_LEN - temp < pfb_len + 6 ) { FT_TRACE2(( " MacOS resource length cannot exceed" - " 0x%08x\n", + " 0x%08lx\n", FT_MAC_RFORK_MAX_LEN )); error = FT_THROW( Invalid_Offset ); @@ -1861,20 +1999,20 @@ } FT_TRACE2(( " total buffer size to concatenate" - " %d POST fragments: 0x%08x\n", + " %ld POST fragments: 0x%08lx\n", resource_cnt, pfb_len + 2 )); if ( pfb_len + 2 < 6 ) { FT_TRACE2(( " too long fragment length makes" - " pfb_len confused: pfb_len=0x%08x\n", + " pfb_len confused: pfb_len=0x%08lx\n", pfb_len )); error = FT_THROW( Array_Too_Large ); goto Exit; } - if ( FT_ALLOC( pfb_data, (FT_Long)pfb_len + 2 ) ) + if ( FT_QALLOC( pfb_data, (FT_Long)pfb_len + 2 ) ) goto Exit; pfb_data[0] = 0x80; @@ -1910,7 +2048,7 @@ goto Exit2; FT_TRACE3(( "POST fragment[%d]:" - " offsets=0x%08x, rlen=0x%08x, flags=0x%04x\n", + " offsets=0x%08lx, rlen=0x%08lx, flags=0x%04x\n", i, offsets[i], rlen, flags )); error = FT_ERR( Array_Too_Large ); @@ -1937,8 +2075,8 @@ else { FT_TRACE3(( " Write POST fragment #%d header (4-byte) to buffer" - " %p + 0x%08x\n", - i, pfb_data, pfb_lenpos )); + " %p + 0x%08lx\n", + i, (void*)pfb_data, pfb_lenpos )); if ( pfb_lenpos + 3 > pfb_len + 2 ) goto Exit2; @@ -1952,8 +2090,8 @@ break; FT_TRACE3(( " Write POST fragment #%d header (6-byte) to buffer" - " %p + 0x%08x\n", - i, pfb_data, pfb_pos )); + " %p + 0x%08lx\n", + i, (void*)pfb_data, pfb_pos )); if ( pfb_pos + 6 > pfb_len + 2 ) goto Exit2; @@ -1974,9 +2112,9 @@ if ( pfb_pos > pfb_len || pfb_pos + rlen > pfb_len ) goto Exit2; - FT_TRACE3(( " Load POST fragment #%d (%d byte) to buffer" - " %p + 0x%08x\n", - i, rlen, pfb_data, pfb_pos )); + FT_TRACE3(( " Load POST fragment #%d (%ld byte) to buffer" + " %p + 0x%08lx\n", + i, rlen, (void*)pfb_data, pfb_pos )); error = FT_Stream_Read( stream, (FT_Byte *)pfb_data + pfb_pos, rlen ); if ( error ) @@ -2074,7 +2212,7 @@ if ( error ) goto Exit; - if ( FT_ALLOC( sfnt_data, rlen ) ) + if ( FT_QALLOC( sfnt_data, rlen ) ) return error; error = FT_Stream_Read( stream, (FT_Byte *)sfnt_data, (FT_ULong)rlen ); if ( error ) { @@ -2260,7 +2398,7 @@ args2.flags = FT_OPEN_PATHNAME; args2.pathname = file_names[i] ? file_names[i] : args->pathname; - FT_TRACE3(( "Try rule %d: %s (offset=%d) ...", + FT_TRACE3(( "Try rule %d: %s (offset=%ld) ...", i, args2.pathname, offsets[i] )); error = FT_Stream_New( library, &args2, &stream2 ); @@ -2389,6 +2527,16 @@ #endif + /* only use lower 31 bits together with sign bit */ + if ( face_index > 0 ) + face_index &= 0x7FFFFFFFL; + else + { + face_index = -face_index; + face_index &= 0x7FFFFFFFL; + face_index = -face_index; + } + #ifdef FT_DEBUG_LEVEL_TRACE FT_TRACE3(( "FT_Open_Face: " )); if ( face_index < 0 ) @@ -2548,7 +2696,7 @@ FT_TRACE4(( "FT_Open_Face: New face object, adding to list\n" )); /* add the face object to its driver's list */ - if ( FT_NEW( node ) ) + if ( FT_QNEW( node ) ) goto Fail; node->data = face; @@ -2663,10 +2811,10 @@ #ifdef FT_DEBUG_LEVEL_TRACE if ( !error && face_index < 0 ) { - FT_TRACE3(( "FT_Open_Face: The font has %ld face%s\n" - " and %ld named instance%s for face %ld\n", + FT_TRACE3(( "FT_Open_Face: The font has %ld face%s\n", face->num_faces, - face->num_faces == 1 ? "" : "s", + face->num_faces == 1 ? "" : "s" )); + FT_TRACE3(( " and %ld named instance%s for face %ld\n", face->style_flags >> 16, ( face->style_flags >> 16 ) == 1 ? "" : "s", -face_index - 1 )); @@ -2833,7 +2981,7 @@ memory = face->memory; /* Allocate new size object and perform basic initialisation */ - if ( FT_ALLOC( size, clazz->size_object_size ) || FT_NEW( node ) ) + if ( FT_ALLOC( size, clazz->size_object_size ) || FT_QNEW( node ) ) goto Exit; size->face = face; @@ -2858,6 +3006,8 @@ if ( error ) { FT_FREE( node ); + if ( size ) + FT_FREE( size->internal ); FT_FREE( size ); } @@ -3068,10 +3218,12 @@ } - FT_BASE_DEF( void ) + FT_BASE_DEF( FT_Error ) FT_Request_Metrics( FT_Face face, FT_Size_Request req ) { + FT_Error error = FT_Err_Ok; + FT_Size_Metrics* metrics; @@ -3162,8 +3314,18 @@ scaled_h = FT_MulFix( face->units_per_EM, metrics->y_scale ); } - metrics->x_ppem = (FT_UShort)( ( scaled_w + 32 ) >> 6 ); - metrics->y_ppem = (FT_UShort)( ( scaled_h + 32 ) >> 6 ); + scaled_w = ( scaled_w + 32 ) >> 6; + scaled_h = ( scaled_h + 32 ) >> 6; + if ( scaled_w > (FT_Long)FT_USHORT_MAX || + scaled_h > (FT_Long)FT_USHORT_MAX ) + { + FT_ERROR(( "FT_Request_Metrics: Resulting ppem size too large\n" )); + error = FT_ERR( Invalid_Pixel_Size ); + goto Exit; + } + + metrics->x_ppem = (FT_UShort)scaled_w; + metrics->y_ppem = (FT_UShort)scaled_h; ft_recompute_scaled_metrics( face, metrics ); } @@ -3173,6 +3335,9 @@ metrics->x_scale = 1L << 16; metrics->y_scale = 1L << 16; } + + Exit: + return error; } @@ -3213,9 +3378,9 @@ FT_Size_Metrics* metrics = &face->size->metrics; - FT_TRACE5(( " x scale: %d (%f)\n", + FT_TRACE5(( " x scale: %ld (%f)\n", metrics->x_scale, metrics->x_scale / 65536.0 )); - FT_TRACE5(( " y scale: %d (%f)\n", + FT_TRACE5(( " y scale: %ld (%f)\n", metrics->y_scale, metrics->y_scale / 65536.0 )); FT_TRACE5(( " ascender: %f\n", metrics->ascender / 64.0 )); FT_TRACE5(( " descender: %f\n", metrics->descender / 64.0 )); @@ -3236,7 +3401,7 @@ FT_Request_Size( FT_Face face, FT_Size_Request req ) { - FT_Error error = FT_Err_Ok; + FT_Error error; FT_Driver_Class clazz; FT_ULong strike_index; @@ -3244,6 +3409,9 @@ if ( !face ) return FT_THROW( Invalid_Face_Handle ); + if ( !face->size ) + return FT_THROW( Invalid_Size_Handle ); + if ( !req || req->width < 0 || req->height < 0 || req->type >= FT_SIZE_REQUEST_TYPE_MAX ) return FT_THROW( Invalid_Argument ); @@ -3272,13 +3440,15 @@ */ error = FT_Match_Size( face, req, 0, &strike_index ); if ( error ) - return error; + goto Exit; return FT_Select_Size( face, (FT_Int)strike_index ); } else { - FT_Request_Metrics( face, req ); + error = FT_Request_Metrics( face, req ); + if ( error ) + goto Exit; FT_TRACE5(( "FT_Request_Size:\n" )); } @@ -3288,9 +3458,9 @@ FT_Size_Metrics* metrics = &face->size->metrics; - FT_TRACE5(( " x scale: %d (%f)\n", + FT_TRACE5(( " x scale: %ld (%f)\n", metrics->x_scale, metrics->x_scale / 65536.0 )); - FT_TRACE5(( " y scale: %d (%f)\n", + FT_TRACE5(( " y scale: %ld (%f)\n", metrics->y_scale, metrics->y_scale / 65536.0 )); FT_TRACE5(( " ascender: %f\n", metrics->ascender / 64.0 )); FT_TRACE5(( " descender: %f\n", metrics->descender / 64.0 )); @@ -3301,6 +3471,7 @@ } #endif + Exit: return error; } @@ -3450,7 +3621,7 @@ if ( akerning->x != orig_x_rounded || akerning->y != orig_y_rounded ) FT_TRACE5(( "FT_Get_Kerning: horizontal kerning" - " (%d, %d) scaled down to (%d, %d) pixels\n", + " (%ld, %ld) scaled down to (%ld, %ld) pixels\n", orig_x_rounded / 64, orig_y_rounded / 64, akerning->x / 64, akerning->y / 64 )); } @@ -3625,9 +3796,9 @@ FT_CharMap last_charmap = face->charmaps[face->num_charmaps - 1]; - if ( FT_RENEW_ARRAY( face->charmaps, - face->num_charmaps, - face->num_charmaps - 1 ) ) + if ( FT_QRENEW_ARRAY( face->charmaps, + face->num_charmaps, + face->num_charmaps - 1 ) ) return; /* remove it from our list of charmaps */ @@ -3659,7 +3830,7 @@ FT_CharMap charmap, FT_CMap *acmap ) { - FT_Error error = FT_Err_Ok; + FT_Error error; FT_Face face; FT_Memory memory; FT_CMap cmap = NULL; @@ -3684,9 +3855,9 @@ } /* add it to our list of charmaps */ - if ( FT_RENEW_ARRAY( face->charmaps, - face->num_charmaps, - face->num_charmaps + 1 ) ) + if ( FT_QRENEW_ARRAY( face->charmaps, + face->num_charmaps, + face->num_charmaps + 1 ) ) goto Fail; face->charmaps[face->num_charmaps++] = (FT_CharMap)cmap; @@ -3722,7 +3893,7 @@ if ( charcode > 0xFFFFFFFFUL ) { FT_TRACE1(( "FT_Get_Char_Index: too large charcode" )); - FT_TRACE1(( " 0x%x is truncated\n", charcode )); + FT_TRACE1(( " 0x%lx is truncated\n", charcode )); } result = cmap->clazz->char_index( cmap, (FT_UInt32)charcode ); @@ -3898,13 +4069,13 @@ { FT_TRACE1(( "FT_Face_GetCharVariantIndex:" " too large charcode" )); - FT_TRACE1(( " 0x%x is truncated\n", charcode )); + FT_TRACE1(( " 0x%lx is truncated\n", charcode )); } if ( variantSelector > 0xFFFFFFFFUL ) { FT_TRACE1(( "FT_Face_GetCharVariantIndex:" " too large variantSelector" )); - FT_TRACE1(( " 0x%x is truncated\n", variantSelector )); + FT_TRACE1(( " 0x%lx is truncated\n", variantSelector )); } result = vcmap->clazz->char_var_index( vcmap, ucmap, @@ -3941,13 +4112,13 @@ { FT_TRACE1(( "FT_Face_GetCharVariantIsDefault:" " too large charcode" )); - FT_TRACE1(( " 0x%x is truncated\n", charcode )); + FT_TRACE1(( " 0x%lx is truncated\n", charcode )); } if ( variantSelector > 0xFFFFFFFFUL ) { FT_TRACE1(( "FT_Face_GetCharVariantIsDefault:" " too large variantSelector" )); - FT_TRACE1(( " 0x%x is truncated\n", variantSelector )); + FT_TRACE1(( " 0x%lx is truncated\n", variantSelector )); } result = vcmap->clazz->char_var_default( vcmap, @@ -4010,7 +4181,7 @@ if ( charcode > 0xFFFFFFFFUL ) { FT_TRACE1(( "FT_Face_GetVariantsOfChar: too large charcode" )); - FT_TRACE1(( " 0x%x is truncated\n", charcode )); + FT_TRACE1(( " 0x%lx is truncated\n", charcode )); } result = vcmap->clazz->charvariant_list( vcmap, memory, @@ -4044,7 +4215,7 @@ if ( variantSelector > 0xFFFFFFFFUL ) { FT_TRACE1(( "FT_Get_Char_Index: too large variantSelector" )); - FT_TRACE1(( " 0x%x is truncated\n", variantSelector )); + FT_TRACE1(( " 0x%lx is truncated\n", variantSelector )); } result = vcmap->clazz->variantchar_list( vcmap, memory, @@ -4380,7 +4551,7 @@ FT_ListNode node = NULL; - if ( FT_NEW( node ) ) + if ( FT_QNEW( node ) ) goto Exit; { @@ -4392,8 +4563,7 @@ render->glyph_format = clazz->glyph_format; /* allocate raster object if needed */ - if ( clazz->glyph_format == FT_GLYPH_FORMAT_OUTLINE && - clazz->raster_class->raster_new ) + if ( clazz->raster_class && clazz->raster_class->raster_new ) { error = clazz->raster_class->raster_new( memory, &render->raster ); if ( error ) @@ -4403,6 +4573,11 @@ render->render = clazz->render_glyph; } +#ifdef FT_CONFIG_OPTION_SVG + if ( clazz->glyph_format == FT_GLYPH_FORMAT_SVG ) + render->render = clazz->render_glyph; +#endif + /* add to list */ node->data = module; FT_List_Add( &library->renderers, node ); @@ -4440,8 +4615,7 @@ /* release raster object, if any */ - if ( render->clazz->glyph_format == FT_GLYPH_FORMAT_OUTLINE && - render->raster ) + if ( render->raster ) render->clazz->raster_class->raster_done( render->raster ); /* remove from list */ @@ -4536,9 +4710,6 @@ switch ( slot->format ) { - case FT_GLYPH_FORMAT_BITMAP: /* already a bitmap, don't do anything */ - break; - default: if ( slot->internal->load_flags & FT_LOAD_COLOR ) { @@ -4626,7 +4797,7 @@ else renderer = FT_Lookup_Renderer( library, slot->format, &node ); - error = FT_ERR( Unimplemented_Feature ); + error = FT_ERR( Cannot_Render_Glyph ); while ( renderer ) { error = renderer->render( renderer, slot, render_mode, NULL ); @@ -4642,6 +4813,11 @@ /* format. */ renderer = FT_Lookup_Renderer( library, slot->format, &node ); } + + /* it is not an error if we cannot render a bitmap glyph */ + if ( FT_ERR_EQ( error, Cannot_Render_Glyph ) && + slot->format == FT_GLYPH_FORMAT_BITMAP ) + error = FT_Err_Ok; } } @@ -4714,11 +4890,11 @@ /* we use FT_TRACE7 in this block */ if ( !error && - ft_trace_levels[trace_checksum] >= 7 ) + ft_trace_levels[trace_checksum] >= 7 && + slot->bitmap.buffer ) { if ( slot->bitmap.rows < 128U && - slot->bitmap.width < 128U && - slot->bitmap.buffer ) + slot->bitmap.width < 128U ) { int rows = (int)slot->bitmap.rows; int width = (int)slot->bitmap.width; @@ -5129,16 +5305,16 @@ if ( cur == limit ) { - FT_ERROR(( "%s: can't find module `%s'\n", - func_name, module_name )); + FT_TRACE2(( "%s: can't find module `%s'\n", + func_name, module_name )); return FT_THROW( Missing_Module ); } /* check whether we have a service interface */ if ( !cur[0]->clazz->get_interface ) { - FT_ERROR(( "%s: module `%s' doesn't support properties\n", - func_name, module_name )); + FT_TRACE2(( "%s: module `%s' doesn't support properties\n", + func_name, module_name )); return FT_THROW( Unimplemented_Feature ); } @@ -5147,8 +5323,8 @@ FT_SERVICE_ID_PROPERTIES ); if ( !interface ) { - FT_ERROR(( "%s: module `%s' doesn't support properties\n", - func_name, module_name )); + FT_TRACE2(( "%s: module `%s' doesn't support properties\n", + func_name, module_name )); return FT_THROW( Unimplemented_Feature ); } @@ -5161,8 +5337,8 @@ if ( missing_func ) { - FT_ERROR(( "%s: property service of module `%s' is broken\n", - func_name, module_name )); + FT_TRACE2(( "%s: property service of module `%s' is broken\n", + func_name, module_name )); return FT_THROW( Unimplemented_Feature ); } @@ -5272,10 +5448,12 @@ if ( !memory || !alibrary ) return FT_THROW( Invalid_Argument ); +#ifndef FT_DEBUG_LOGGING #ifdef FT_DEBUG_LEVEL_ERROR /* init debugging support */ ft_debug_init(); -#endif +#endif /* FT_DEBUG_LEVEL_ERROR */ +#endif /* !FT_DEBUG_LOGGING */ /* first of all, allocate the library object */ if ( FT_NEW( library ) ) @@ -5547,4 +5725,145 @@ } + /* documentation is in freetype.h */ + + FT_EXPORT_DEF( FT_Bool ) + FT_Get_Color_Glyph_Paint( FT_Face face, + FT_UInt base_glyph, + FT_Color_Root_Transform root_transform, + FT_OpaquePaint* paint ) + { + TT_Face ttface; + SFNT_Service sfnt; + + + if ( !face || !paint ) + return 0; + + if ( !FT_IS_SFNT( face ) ) + return 0; + + ttface = (TT_Face)face; + sfnt = (SFNT_Service)ttface->sfnt; + + if ( sfnt->get_colr_layer ) + return sfnt->get_colr_glyph_paint( ttface, + base_glyph, + root_transform, + paint ); + else + return 0; + } + + + /* documentation is in ftcolor.h */ + + FT_EXPORT_DEF( FT_Bool ) + FT_Get_Color_Glyph_ClipBox( FT_Face face, + FT_UInt base_glyph, + FT_ClipBox* clip_box ) + { + TT_Face ttface; + SFNT_Service sfnt; + + + if ( !face || !clip_box ) + return 0; + + if ( !FT_IS_SFNT( face ) ) + return 0; + + ttface = (TT_Face)face; + sfnt = (SFNT_Service)ttface->sfnt; + + if ( sfnt->get_color_glyph_clipbox ) + return sfnt->get_color_glyph_clipbox( ttface, + base_glyph, + clip_box ); + else + return 0; + } + + + /* documentation is in freetype.h */ + + FT_EXPORT_DEF( FT_Bool ) + FT_Get_Paint_Layers( FT_Face face, + FT_LayerIterator* layer_iterator, + FT_OpaquePaint* paint ) + { + TT_Face ttface; + SFNT_Service sfnt; + + + if ( !face || !paint || !layer_iterator ) + return 0; + + if ( !FT_IS_SFNT( face ) ) + return 0; + + ttface = (TT_Face)face; + sfnt = (SFNT_Service)ttface->sfnt; + + if ( sfnt->get_paint_layers ) + return sfnt->get_paint_layers( ttface, layer_iterator, paint ); + else + return 0; + } + + + /* documentation is in freetype.h */ + + FT_EXPORT_DEF( FT_Bool ) + FT_Get_Paint( FT_Face face, + FT_OpaquePaint opaque_paint, + FT_COLR_Paint* paint ) + { + TT_Face ttface; + SFNT_Service sfnt; + + + if ( !face || !paint ) + return 0; + + if ( !FT_IS_SFNT( face ) ) + return 0; + + ttface = (TT_Face)face; + sfnt = (SFNT_Service)ttface->sfnt; + + if ( sfnt->get_paint ) + return sfnt->get_paint( ttface, opaque_paint, paint ); + else + return 0; + } + + + /* documentation is in freetype.h */ + + FT_EXPORT_DEF( FT_Bool ) + FT_Get_Colorline_Stops ( FT_Face face, + FT_ColorStop * color_stop, + FT_ColorStopIterator *iterator ) + { + TT_Face ttface; + SFNT_Service sfnt; + + + if ( !face || !color_stop || !iterator ) + return 0; + + if ( !FT_IS_SFNT( face ) ) + return 0; + + ttface = (TT_Face)face; + sfnt = (SFNT_Service)ttface->sfnt; + + if ( sfnt->get_colorline_stops ) + return sfnt->get_colorline_stops ( ttface, color_stop, iterator ); + else + return 0; + } + + /* END */ |