summaryrefslogtreecommitdiffstats
path: root/src/3rdparty/freetype/src/base/ftobjs.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/3rdparty/freetype/src/base/ftobjs.c')
-rw-r--r--src/3rdparty/freetype/src/base/ftobjs.c569
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 */