summaryrefslogtreecommitdiffstats
path: root/modules/freetype2/src/base/ftobjs.c
diff options
context:
space:
mode:
Diffstat (limited to 'modules/freetype2/src/base/ftobjs.c')
-rw-r--r--modules/freetype2/src/base/ftobjs.c628
1 files changed, 463 insertions, 165 deletions
diff --git a/modules/freetype2/src/base/ftobjs.c b/modules/freetype2/src/base/ftobjs.c
index 4f2a9ecdb..8d07e35ae 100644
--- a/modules/freetype2/src/base/ftobjs.c
+++ b/modules/freetype2/src/base/ftobjs.c
@@ -4,7 +4,7 @@
/* */
/* The FreeType private base classes (body). */
/* */
-/* Copyright 1996-2016 by */
+/* Copyright 1996-2018 by */
/* David Turner, Robert Wilhelm, and Werner Lemberg. */
/* */
/* This file is part of the FreeType project, and may only be used, */
@@ -19,12 +19,16 @@
#include <ft2build.h>
#include FT_LIST_H
#include FT_OUTLINE_H
+#include FT_FONT_FORMATS_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_SFNT_H /* for SFNT_Load_Table_Func */
+#include FT_INTERNAL_POSTSCRIPT_AUX_H /* for PS_Driver */
+
#include FT_TRUETYPE_TABLES_H
#include FT_TRUETYPE_TAGS_H
#include FT_TRUETYPE_IDS_H
@@ -37,6 +41,8 @@
#include FT_SERVICE_KERNING_H
#include FT_SERVICE_TRUETYPE_ENGINE_H
+#include FT_DRIVER_H
+
#ifdef FT_CONFIG_OPTION_MAC_FONTS
#include "ftbase.h"
#endif
@@ -325,6 +331,138 @@
FT_BASE_DEF( void )
+ ft_glyphslot_preset_bitmap( FT_GlyphSlot slot,
+ FT_Render_Mode mode,
+ const FT_Vector* origin )
+ {
+ FT_Outline* outline = &slot->outline;
+ FT_Bitmap* bitmap = &slot->bitmap;
+
+ FT_Pixel_Mode pixel_mode;
+
+ FT_BBox cbox;
+ FT_Pos x_shift = 0;
+ FT_Pos y_shift = 0;
+ FT_Pos x_left, y_top;
+ FT_Pos width, height, pitch;
+
+
+ if ( slot->internal && ( slot->internal->flags & FT_GLYPH_OWN_BITMAP ) )
+ return;
+
+ if ( origin )
+ {
+ x_shift = origin->x;
+ y_shift = origin->y;
+ }
+
+ /* compute the control box, and grid-fit it, */
+ /* taking into account the origin shift */
+ FT_Outline_Get_CBox( outline, &cbox );
+
+ cbox.xMin += x_shift;
+ cbox.yMin += y_shift;
+ cbox.xMax += x_shift;
+ cbox.yMax += y_shift;
+
+ switch ( mode )
+ {
+ case FT_RENDER_MODE_MONO:
+ pixel_mode = FT_PIXEL_MODE_MONO;
+#if 1
+ /* undocumented but confirmed: bbox values get rounded */
+ /* unless the rounded box can collapse for a narrow glyph */
+ if ( cbox.xMax - cbox.xMin < 64 )
+ {
+ cbox.xMin = FT_PIX_FLOOR( cbox.xMin );
+ cbox.xMax = FT_PIX_CEIL_LONG( cbox.xMax );
+ }
+ else
+ {
+ cbox.xMin = FT_PIX_ROUND_LONG( cbox.xMin );
+ cbox.xMax = FT_PIX_ROUND_LONG( cbox.xMax );
+ }
+
+ if ( cbox.yMax - cbox.yMin < 64 )
+ {
+ cbox.yMin = FT_PIX_FLOOR( cbox.yMin );
+ cbox.yMax = FT_PIX_CEIL_LONG( cbox.yMax );
+ }
+ else
+ {
+ cbox.yMin = FT_PIX_ROUND_LONG( cbox.yMin );
+ cbox.yMax = FT_PIX_ROUND_LONG( cbox.yMax );
+ }
+#else
+ cbox.xMin = FT_PIX_FLOOR( cbox.xMin );
+ cbox.yMin = FT_PIX_FLOOR( cbox.yMin );
+ cbox.xMax = FT_PIX_CEIL_LONG( cbox.xMax );
+ cbox.yMax = FT_PIX_CEIL_LONG( cbox.yMax );
+#endif
+ break;
+
+ case FT_RENDER_MODE_LCD:
+ pixel_mode = FT_PIXEL_MODE_LCD;
+ ft_lcd_padding( &cbox.xMin, &cbox.xMax, slot );
+ goto Round;
+
+ case FT_RENDER_MODE_LCD_V:
+ pixel_mode = FT_PIXEL_MODE_LCD_V;
+ ft_lcd_padding( &cbox.yMin, &cbox.yMax, slot );
+ goto Round;
+
+ case FT_RENDER_MODE_NORMAL:
+ case FT_RENDER_MODE_LIGHT:
+ default:
+ pixel_mode = FT_PIXEL_MODE_GRAY;
+ Round:
+ cbox.xMin = FT_PIX_FLOOR( cbox.xMin );
+ cbox.yMin = FT_PIX_FLOOR( cbox.yMin );
+ cbox.xMax = FT_PIX_CEIL_LONG( cbox.xMax );
+ cbox.yMax = FT_PIX_CEIL_LONG( cbox.yMax );
+ }
+
+ x_shift = SUB_LONG( x_shift, cbox.xMin );
+ y_shift = SUB_LONG( y_shift, cbox.yMin );
+
+ x_left = cbox.xMin >> 6;
+ y_top = cbox.yMax >> 6;
+
+ width = ( (FT_ULong)cbox.xMax - (FT_ULong)cbox.xMin ) >> 6;
+ height = ( (FT_ULong)cbox.yMax - (FT_ULong)cbox.yMin ) >> 6;
+
+ switch ( pixel_mode )
+ {
+ case FT_PIXEL_MODE_MONO:
+ pitch = ( ( width + 15 ) >> 4 ) << 1;
+ break;
+
+ case FT_PIXEL_MODE_LCD:
+ width *= 3;
+ pitch = FT_PAD_CEIL( width, 4 );
+ break;
+
+ case FT_PIXEL_MODE_LCD_V:
+ height *= 3;
+ /* fall through */
+
+ case FT_PIXEL_MODE_GRAY:
+ default:
+ pitch = width;
+ }
+
+ slot->bitmap_left = (FT_Int)x_left;
+ slot->bitmap_top = (FT_Int)y_top;
+
+ bitmap->pixel_mode = (unsigned char)pixel_mode;
+ bitmap->num_grays = 256;
+ bitmap->width = (unsigned int)width;
+ bitmap->rows = (unsigned int)height;
+ bitmap->pitch = pitch;
+ }
+
+
+ FT_BASE_DEF( void )
ft_glyphslot_set_bitmap( FT_GlyphSlot slot,
FT_Byte* buffer )
{
@@ -462,7 +600,8 @@
Exit:
- FT_TRACE4(( "FT_New_GlyphSlot: Return %d\n", error ));
+ FT_TRACE4(( "FT_New_GlyphSlot: Return 0x%x\n", error ));
+
return error;
}
@@ -575,34 +714,42 @@
if ( vertical )
{
metrics->horiBearingX = FT_PIX_FLOOR( metrics->horiBearingX );
- metrics->horiBearingY = FT_PIX_CEIL ( metrics->horiBearingY );
+ metrics->horiBearingY = FT_PIX_CEIL_LONG( metrics->horiBearingY );
- right = FT_PIX_CEIL( metrics->vertBearingX + metrics->width );
- bottom = FT_PIX_CEIL( metrics->vertBearingY + metrics->height );
+ right = FT_PIX_CEIL_LONG( ADD_LONG( metrics->vertBearingX,
+ metrics->width ) );
+ bottom = FT_PIX_CEIL_LONG( ADD_LONG( metrics->vertBearingY,
+ metrics->height ) );
metrics->vertBearingX = FT_PIX_FLOOR( metrics->vertBearingX );
metrics->vertBearingY = FT_PIX_FLOOR( metrics->vertBearingY );
- metrics->width = right - metrics->vertBearingX;
- metrics->height = bottom - metrics->vertBearingY;
+ metrics->width = SUB_LONG( right,
+ metrics->vertBearingX );
+ metrics->height = SUB_LONG( bottom,
+ metrics->vertBearingY );
}
else
{
metrics->vertBearingX = FT_PIX_FLOOR( metrics->vertBearingX );
metrics->vertBearingY = FT_PIX_FLOOR( metrics->vertBearingY );
- right = FT_PIX_CEIL ( metrics->horiBearingX + metrics->width );
- bottom = FT_PIX_FLOOR( metrics->horiBearingY - metrics->height );
+ right = FT_PIX_CEIL_LONG( ADD_LONG( metrics->horiBearingX,
+ metrics->width ) );
+ bottom = FT_PIX_FLOOR( SUB_LONG( metrics->horiBearingY,
+ metrics->height ) );
metrics->horiBearingX = FT_PIX_FLOOR( metrics->horiBearingX );
- metrics->horiBearingY = FT_PIX_CEIL ( metrics->horiBearingY );
+ metrics->horiBearingY = FT_PIX_CEIL_LONG( metrics->horiBearingY );
- metrics->width = right - metrics->horiBearingX;
- metrics->height = metrics->horiBearingY - bottom;
+ metrics->width = SUB_LONG( right,
+ metrics->horiBearingX );
+ metrics->height = SUB_LONG( metrics->horiBearingY,
+ bottom );
}
- metrics->horiAdvance = FT_PIX_ROUND( metrics->horiAdvance );
- metrics->vertAdvance = FT_PIX_ROUND( metrics->vertAdvance );
+ metrics->horiAdvance = FT_PIX_ROUND_LONG( metrics->horiAdvance );
+ metrics->vertAdvance = FT_PIX_ROUND_LONG( metrics->vertAdvance );
}
#endif /* GRID_FIT_METRICS */
@@ -657,9 +804,13 @@
* Determine whether we need to auto-hint or not.
* The general rules are:
*
- * - Do only auto-hinting if we have a hinter module, a scalable font
- * format dealing with outlines, and no transforms except simple
- * slants and/or rotations by integer multiples of 90 degrees.
+ * - Do only auto-hinting if we have
+ *
+ * - a hinter module,
+ * - a scalable font format dealing with outlines,
+ * - not a tricky font, and
+ * - no transforms except simple slants and/or rotations by
+ * integer multiples of 90 degrees.
*
* - Then, auto-hint if FT_LOAD_FORCE_AUTOHINT is set or if we don't
* have a native font hinter.
@@ -689,7 +840,14 @@
else
{
FT_Render_Mode mode = FT_LOAD_TARGET_MODE( load_flags );
+ FT_Bool is_light_type1;
+
+ /* only the new Adobe engine (for both CFF and Type 1) is `light'; */
+ /* we use `strstr' to catch both `Type 1' and `CID Type 1' */
+ is_light_type1 =
+ ft_strstr( FT_Get_Font_Format( face ), "Type 1" ) != NULL &&
+ ((PS_Driver)driver)->hinting_engine == FT_HINTING_ADOBE;
/* the check for `num_locations' assures that we actually */
/* test for instructions in a TTF and not in a CFF-based OTF */
@@ -698,8 +856,9 @@
/* check the size of the `fpgm' and `prep' tables, too -- */
/* the assumption is that there don't exist real TTFs where */
/* both `fpgm' and `prep' tables are missing */
- if ( ( mode == FT_RENDER_MODE_LIGHT &&
- !FT_DRIVER_HINTS_LIGHTLY( driver ) ) ||
+ if ( ( mode == FT_RENDER_MODE_LIGHT &&
+ ( !FT_DRIVER_HINTS_LIGHTLY( driver ) &&
+ !is_light_type1 ) ) ||
( FT_IS_SFNT( face ) &&
ttface->num_locations &&
ttface->max_profile.maxSizeOfInstructions == 0 &&
@@ -719,8 +878,8 @@
/* XXX: This is really a temporary hack that should disappear */
/* promptly with FreeType 2.1! */
/* */
- if ( FT_HAS_FIXED_SIZES( face ) &&
- ( load_flags & FT_LOAD_NO_BITMAP ) == 0 )
+ if ( FT_HAS_FIXED_SIZES( face ) &&
+ ( load_flags & FT_LOAD_NO_BITMAP ) == 0 )
{
error = driver->clazz->load_glyph( slot, face->size,
glyph_index,
@@ -788,7 +947,7 @@
/* compute the linear advance in 16.16 pixels */
if ( ( load_flags & FT_LOAD_LINEAR_DESIGN ) == 0 &&
- ( FT_IS_SCALABLE( face ) ) )
+ FT_IS_SCALABLE( face ) )
{
FT_Size_Metrics* metrics = &face->size->metrics;
@@ -836,28 +995,37 @@
}
}
- FT_TRACE5(( " x advance: %d\n" , slot->advance.x ));
- FT_TRACE5(( " y advance: %d\n" , slot->advance.y ));
-
- FT_TRACE5(( " linear x advance: %d\n" , slot->linearHoriAdvance ));
- FT_TRACE5(( " linear y advance: %d\n" , slot->linearVertAdvance ));
-
- /* do we need to render the image now? */
+ /* do we need to render the image or preset the bitmap now? */
if ( !error &&
+ ( load_flags & FT_LOAD_NO_SCALE ) == 0 &&
slot->format != FT_GLYPH_FORMAT_BITMAP &&
- slot->format != FT_GLYPH_FORMAT_COMPOSITE &&
- load_flags & FT_LOAD_RENDER )
+ slot->format != FT_GLYPH_FORMAT_COMPOSITE )
{
FT_Render_Mode mode = FT_LOAD_TARGET_MODE( load_flags );
- if ( mode == FT_RENDER_MODE_NORMAL &&
- (load_flags & FT_LOAD_MONOCHROME ) )
+ if ( mode == FT_RENDER_MODE_NORMAL &&
+ load_flags & FT_LOAD_MONOCHROME )
mode = FT_RENDER_MODE_MONO;
- error = FT_Render_Glyph( slot, mode );
+ if ( load_flags & FT_LOAD_RENDER )
+ error = FT_Render_Glyph( slot, mode );
+ else
+ ft_glyphslot_preset_bitmap( slot, mode, NULL );
}
+ FT_TRACE5(( "FT_Load_Glyph: index %d, flags %x\n",
+ glyph_index, load_flags ));
+ 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, mode %d\n",
+ slot->bitmap.width, slot->bitmap.rows,
+ slot->bitmap.pixel_mode ));
+
Exit:
return error;
}
@@ -1185,6 +1353,8 @@
}
#endif
+ face->internal->random_seed = -1;
+
if ( clazz->init_face )
error = clazz->init_face( *astream,
face,
@@ -2031,13 +2201,15 @@
{
FT_TRACE3(( "Skip rule %d: darwin vfs resource fork"
" is already checked and"
- " no font is found\n", i ));
+ " no font is found\n",
+ i ));
continue;
}
if ( errors[i] )
{
- FT_TRACE3(( "Error[%d] has occurred in rule %d\n", errors[i], i ));
+ FT_TRACE3(( "Error 0x%x has occurred in rule %d\n",
+ errors[i], i ));
continue;
}
@@ -2396,7 +2568,7 @@
if ( bsize->height < 0 || bsize->x_ppem < 0 || bsize->y_ppem < 0 )
{
FT_TRACE0(( "FT_Open_Face:"
- " Invalid bitmap dimensions for stroke %d,"
+ " Invalid bitmap dimensions for strike %d,"
" now disabled\n", i ));
bsize->width = 0;
bsize->height = 0;
@@ -2421,6 +2593,13 @@
internal->transform_delta.y = 0;
internal->refcount = 1;
+
+ internal->no_stem_darkening = -1;
+
+#ifdef FT_CONFIG_OPTION_SUBPIXEL_RENDERING
+ /* Per-face filtering can only be set up by FT_Face_Properties */
+ internal->lcd_filter_func = NULL;
+#endif
}
if ( aface )
@@ -2440,15 +2619,17 @@
#ifdef FT_DEBUG_LEVEL_TRACE
if ( !error && face_index < 0 )
{
- FT_TRACE3(( "FT_Open_Face: The font has %ld faces\n"
- " and %ld named instances for face %ld\n",
+ FT_TRACE3(( "FT_Open_Face: The font has %ld face%s\n"
+ " and %ld named instance%s for face %ld\n",
face->num_faces,
+ face->num_faces == 1 ? "" : "s",
face->style_flags >> 16,
+ ( face->style_flags >> 16 ) == 1 ? "" : "s",
-face_index - 1 ));
}
#endif
- FT_TRACE4(( "FT_Open_Face: Return %d\n", error ));
+ FT_TRACE4(( "FT_Open_Face: Return 0x%x\n", error ));
return error;
}
@@ -2589,6 +2770,8 @@
FT_Size size = NULL;
FT_ListNode node = NULL;
+ FT_Size_Internal internal = NULL;
+
if ( !face )
return FT_THROW( Invalid_Face_Handle );
@@ -2611,8 +2794,10 @@
size->face = face;
- /* for now, do not use any internal fields in size objects */
- size->internal = NULL;
+ if ( FT_NEW( internal ) )
+ goto Exit;
+
+ size->internal = internal;
if ( clazz->init_size )
error = clazz->init_size( size );
@@ -2836,18 +3021,6 @@
metrics->height = bsize->height << 6;
metrics->max_advance = bsize->x_ppem;
}
-
- FT_TRACE5(( "FT_Select_Metrics:\n" ));
- FT_TRACE5(( " x scale: %d (%f)\n",
- metrics->x_scale, metrics->x_scale / 65536.0 ));
- FT_TRACE5(( " y scale: %d (%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 ));
- FT_TRACE5(( " height: %f\n", metrics->height / 64.0 ));
- FT_TRACE5(( " max advance: %f\n", metrics->max_advance / 64.0 ));
- FT_TRACE5(( " x ppem: %d\n", metrics->x_ppem ));
- FT_TRACE5(( " y ppem: %d\n", metrics->y_ppem ));
}
@@ -2956,18 +3129,6 @@
metrics->x_scale = 1L << 16;
metrics->y_scale = 1L << 16;
}
-
- FT_TRACE5(( "FT_Request_Metrics:\n" ));
- FT_TRACE5(( " x scale: %d (%f)\n",
- metrics->x_scale, metrics->x_scale / 65536.0 ));
- FT_TRACE5(( " y scale: %d (%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 ));
- FT_TRACE5(( " height: %f\n", metrics->height / 64.0 ));
- FT_TRACE5(( " max advance: %f\n", metrics->max_advance / 64.0 ));
- FT_TRACE5(( " x ppem: %d\n", metrics->x_ppem ));
- FT_TRACE5(( " y ppem: %d\n", metrics->y_ppem ));
}
@@ -2977,6 +3138,7 @@
FT_Select_Size( FT_Face face,
FT_Int strike_index )
{
+ FT_Error error = FT_Err_Ok;
FT_Driver_Class clazz;
@@ -2990,36 +3152,37 @@
if ( clazz->select_size )
{
- FT_Error error;
+ error = clazz->select_size( face->size, (FT_ULong)strike_index );
+ FT_TRACE5(( "FT_Select_Size (%s driver):\n",
+ face->driver->root.clazz->module_name ));
+ }
+ else
+ {
+ FT_Select_Metrics( face, (FT_ULong)strike_index );
- error = clazz->select_size( face->size, (FT_ULong)strike_index );
+ FT_TRACE5(( "FT_Select_Size:\n" ));
+ }
#ifdef FT_DEBUG_LEVEL_TRACE
- {
- FT_Size_Metrics* metrics = &face->size->metrics;
-
-
- FT_TRACE5(( "FT_Select_Size (font driver's `select_size'):\n" ));
- FT_TRACE5(( " x scale: %d (%f)\n",
- metrics->x_scale, metrics->x_scale / 65536.0 ));
- FT_TRACE5(( " y scale: %d (%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 ));
- FT_TRACE5(( " height: %f\n", metrics->height / 64.0 ));
- FT_TRACE5(( " max advance: %f\n", metrics->max_advance / 64.0 ));
- FT_TRACE5(( " x ppem: %d\n", metrics->x_ppem ));
- FT_TRACE5(( " y ppem: %d\n", metrics->y_ppem ));
- }
-#endif
+ {
+ FT_Size_Metrics* metrics = &face->size->metrics;
- return error;
- }
- FT_Select_Metrics( face, (FT_ULong)strike_index );
+ FT_TRACE5(( " x scale: %d (%f)\n",
+ metrics->x_scale, metrics->x_scale / 65536.0 ));
+ FT_TRACE5(( " y scale: %d (%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 ));
+ FT_TRACE5(( " height: %f\n", metrics->height / 64.0 ));
+ FT_TRACE5(( " max advance: %f\n", metrics->max_advance / 64.0 ));
+ FT_TRACE5(( " x ppem: %d\n", metrics->x_ppem ));
+ FT_TRACE5(( " y ppem: %d\n", metrics->y_ppem ));
+ }
+#endif
- return FT_Err_Ok;
+ return error;
}
@@ -3029,6 +3192,7 @@
FT_Request_Size( FT_Face face,
FT_Size_Request req )
{
+ FT_Error error = FT_Err_Ok;
FT_Driver_Class clazz;
FT_ULong strike_index;
@@ -3040,59 +3204,60 @@
req->type >= FT_SIZE_REQUEST_TYPE_MAX )
return FT_THROW( Invalid_Argument );
+ /* signal the auto-hinter to recompute its size metrics */
+ /* (if requested) */
+ face->size->internal->autohint_metrics.x_scale = 0;
+
clazz = face->driver->clazz;
if ( clazz->request_size )
{
- FT_Error error;
-
-
error = clazz->request_size( face->size, req );
-#ifdef FT_DEBUG_LEVEL_TRACE
- {
- FT_Size_Metrics* metrics = &face->size->metrics;
-
-
- FT_TRACE5(( "FT_Request_Size (font driver's `request_size'):\n" ));
- FT_TRACE5(( " x scale: %d (%f)\n",
- metrics->x_scale, metrics->x_scale / 65536.0 ));
- FT_TRACE5(( " y scale: %d (%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 ));
- FT_TRACE5(( " height: %f\n", metrics->height / 64.0 ));
- FT_TRACE5(( " max advance: %f\n", metrics->max_advance / 64.0 ));
- FT_TRACE5(( " x ppem: %d\n", metrics->x_ppem ));
- FT_TRACE5(( " y ppem: %d\n", metrics->y_ppem ));
- }
-#endif
-
- return error;
+ FT_TRACE5(( "FT_Request_Size (%s driver):\n",
+ face->driver->root.clazz->module_name ));
}
-
- /*
- * The reason that a driver doesn't have `request_size' defined is
- * either that the scaling here suffices or that the supported formats
- * are bitmap-only and size matching is not implemented.
- *
- * In the latter case, a simple size matching is done.
- */
- if ( !FT_IS_SCALABLE( face ) && FT_HAS_FIXED_SIZES( face ) )
+ else if ( !FT_IS_SCALABLE( face ) && FT_HAS_FIXED_SIZES( face ) )
{
- FT_Error error;
-
-
+ /*
+ * The reason that a driver doesn't have `request_size' defined is
+ * either that the scaling here suffices or that the supported formats
+ * are bitmap-only and size matching is not implemented.
+ *
+ * In the latter case, a simple size matching is done.
+ */
error = FT_Match_Size( face, req, 0, &strike_index );
if ( error )
return error;
return FT_Select_Size( face, (FT_Int)strike_index );
}
+ else
+ {
+ FT_Request_Metrics( face, req );
+
+ FT_TRACE5(( "FT_Request_Size:\n" ));
+ }
+
+#ifdef FT_DEBUG_LEVEL_TRACE
+ {
+ FT_Size_Metrics* metrics = &face->size->metrics;
- FT_Request_Metrics( face, req );
- return FT_Err_Ok;
+ FT_TRACE5(( " x scale: %d (%f)\n",
+ metrics->x_scale, metrics->x_scale / 65536.0 ));
+ FT_TRACE5(( " y scale: %d (%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 ));
+ FT_TRACE5(( " height: %f\n", metrics->height / 64.0 ));
+ FT_TRACE5(( " max advance: %f\n", metrics->max_advance / 64.0 ));
+ FT_TRACE5(( " x ppem: %d\n", metrics->x_ppem ));
+ FT_TRACE5(( " y ppem: %d\n", metrics->y_ppem ));
+ }
+#endif
+
+ return error;
}
@@ -3586,6 +3751,85 @@
/* documentation is in freetype.h */
+ FT_EXPORT_DEF( FT_Error )
+ FT_Face_Properties( FT_Face face,
+ FT_UInt num_properties,
+ FT_Parameter* properties )
+ {
+ FT_Error error = FT_Err_Ok;
+
+
+ if ( num_properties > 0 && !properties )
+ {
+ error = FT_THROW( Invalid_Argument );
+ goto Exit;
+ }
+
+ for ( ; num_properties > 0; num_properties-- )
+ {
+ if ( properties->tag == FT_PARAM_TAG_STEM_DARKENING )
+ {
+ if ( properties->data )
+ {
+ if ( *( (FT_Bool*)properties->data ) == TRUE )
+ face->internal->no_stem_darkening = FALSE;
+ else
+ face->internal->no_stem_darkening = TRUE;
+ }
+ else
+ {
+ /* use module default */
+ face->internal->no_stem_darkening = -1;
+ }
+ }
+ else if ( properties->tag == FT_PARAM_TAG_LCD_FILTER_WEIGHTS )
+ {
+#ifdef FT_CONFIG_OPTION_SUBPIXEL_RENDERING
+ if ( properties->data )
+ {
+ ft_memcpy( face->internal->lcd_weights,
+ properties->data,
+ FT_LCD_FILTER_FIVE_TAPS );
+ face->internal->lcd_filter_func = ft_lcd_filter_fir;
+ }
+#else
+ error = FT_THROW( Unimplemented_Feature );
+ goto Exit;
+#endif
+ }
+ else if ( properties->tag == FT_PARAM_TAG_RANDOM_SEED )
+ {
+ if ( properties->data )
+ {
+ face->internal->random_seed = *( (FT_Int32*)properties->data );
+ if ( face->internal->random_seed < 0 )
+ face->internal->random_seed = 0;
+ }
+ else
+ {
+ /* use module default */
+ face->internal->random_seed = -1;
+ }
+ }
+ else
+ {
+ error = FT_THROW( Invalid_Argument );
+ goto Exit;
+ }
+
+ if ( error )
+ break;
+
+ properties++;
+ }
+
+ Exit:
+ return error;
+ }
+
+
+ /* documentation is in freetype.h */
+
FT_EXPORT_DEF( FT_UInt )
FT_Face_GetCharVariantIndex( FT_Face face,
FT_ULong charcode,
@@ -3609,12 +3853,14 @@
if ( charcode > 0xFFFFFFFFUL )
{
- FT_TRACE1(( "FT_Get_Char_Index: too large charcode" ));
+ FT_TRACE1(( "FT_Face_GetCharVariantIndex:"
+ " too large charcode" ));
FT_TRACE1(( " 0x%x is truncated\n", charcode ));
}
if ( variantSelector > 0xFFFFFFFFUL )
{
- FT_TRACE1(( "FT_Get_Char_Index: too large variantSelector" ));
+ FT_TRACE1(( "FT_Face_GetCharVariantIndex:"
+ " too large variantSelector" ));
FT_TRACE1(( " 0x%x is truncated\n", variantSelector ));
}
@@ -3650,12 +3896,14 @@
if ( charcode > 0xFFFFFFFFUL )
{
- FT_TRACE1(( "FT_Get_Char_Index: too large charcode" ));
+ FT_TRACE1(( "FT_Face_GetCharVariantIsDefault:"
+ " too large charcode" ));
FT_TRACE1(( " 0x%x is truncated\n", charcode ));
}
if ( variantSelector > 0xFFFFFFFFUL )
{
- FT_TRACE1(( "FT_Get_Char_Index: too large variantSelector" ));
+ FT_TRACE1(( "FT_Face_GetCharVariantIsDefault:"
+ " too large variantSelector" ));
FT_TRACE1(( " 0x%x is truncated\n", variantSelector ));
}
@@ -3718,7 +3966,7 @@
if ( charcode > 0xFFFFFFFFUL )
{
- FT_TRACE1(( "FT_Get_Char_Index: too large charcode" ));
+ FT_TRACE1(( "FT_Face_GetVariantsOfChar: too large charcode" ));
FT_TRACE1(( " 0x%x is truncated\n", charcode ));
}
@@ -4294,43 +4542,97 @@
*/
/* we use FT_TRACE3 in this block */
- if ( ft_trace_levels[trace_bitmap] >= 3 )
+ if ( !error &&
+ ft_trace_levels[trace_bitmap] >= 3 &&
+ slot->bitmap.buffer )
{
+ FT_Bitmap bitmap;
+ FT_Error err;
+
+
+ FT_Bitmap_Init( &bitmap );
+
/* we convert to a single bitmap format for computing the checksum */
- if ( !error && slot->bitmap.buffer )
+ /* this also converts the bitmap flow to `down' (i.e., pitch > 0) */
+ err = FT_Bitmap_Convert( library, &slot->bitmap, &bitmap, 1 );
+ if ( !err )
{
- FT_Bitmap bitmap;
- FT_Error err;
+ MD5_CTX ctx;
+ unsigned char md5[16];
+ unsigned long coverage = 0;
+ int i, j;
+ int rows = (int)bitmap.rows;
+ int pitch = bitmap.pitch;
+
+
+ FT_TRACE3(( "FT_Render_Glyph: bitmap %dx%d, mode %d\n",
+ rows, pitch, slot->bitmap.pixel_mode ));
+
+ for ( i = 0; i < rows; i++ )
+ for ( j = 0; j < pitch; j++ )
+ coverage += bitmap.buffer[i * pitch + j];
+
+ FT_TRACE3(( " Total coverage: %lu\n", coverage ));
+
+ MD5_Init( &ctx );
+ if ( bitmap.buffer )
+ MD5_Update( &ctx, bitmap.buffer,
+ (unsigned long)rows * (unsigned long)pitch );
+ MD5_Final( md5, &ctx );
+
+ FT_TRACE3(( " MD5 checksum: " ));
+ for ( i = 0; i < 16; i++ )
+ FT_TRACE3(( "%02X", md5[i] ));
+ FT_TRACE3(( "\n" ));
+ }
+
+ FT_Bitmap_Done( library, &bitmap );
+ }
+
+ /*
+ * Dump bitmap in Netpbm format (PBM or PGM).
+ */
+ /* we use FT_TRACE7 in this block */
+ if ( !error &&
+ ft_trace_levels[trace_bitmap] >= 7 &&
+ slot->bitmap.rows < 128U &&
+ slot->bitmap.width < 128U &&
+ slot->bitmap.buffer )
+ {
+ int rows = (int)slot->bitmap.rows;
+ int width = (int)slot->bitmap.width;
+ int pitch = slot->bitmap.pitch;
+ int i, j, m;
+ unsigned char* topleft = slot->bitmap.buffer;
- FT_Bitmap_Init( &bitmap );
+ if ( pitch < 0 )
+ topleft -= pitch * ( rows - 1 );
- /* this also converts the bitmap flow to `down' (i.e., pitch > 0) */
- err = FT_Bitmap_Convert( library, &slot->bitmap, &bitmap, 1 );
- if ( !err )
+ FT_TRACE7(( "Netpbm image: start\n" ));
+ switch ( slot->bitmap.pixel_mode )
+ {
+ case FT_PIXEL_MODE_MONO:
+ FT_TRACE7(( "P1 %d %d\n", width, rows ));
+ for ( i = 0; i < rows; i++ )
{
- MD5_CTX ctx;
- unsigned char md5[16];
- int i;
- unsigned int rows = bitmap.rows;
- unsigned int pitch = (unsigned int)bitmap.pitch;
-
-
- MD5_Init( &ctx );
- if ( bitmap.buffer )
- MD5_Update( &ctx, bitmap.buffer, rows * pitch );
- MD5_Final( md5, &ctx );
-
- FT_TRACE3(( "MD5 checksum for %dx%d bitmap:\n"
- " ",
- rows, pitch ));
- for ( i = 0; i < 16; i++ )
- FT_TRACE3(( "%02X", md5[i] ));
- FT_TRACE3(( "\n" ));
+ for ( j = 0; j < width; )
+ for ( m = 128; m > 0 && j < width; m >>= 1, j++ )
+ FT_TRACE7(( " %d", ( topleft[i * pitch + j / 8] & m ) != 0 ));
+ FT_TRACE7(( "\n" ));
}
+ break;
- FT_Bitmap_Done( library, &bitmap );
+ default:
+ FT_TRACE7(( "P2 %d %d 255\n", width, rows ));
+ for ( i = 0; i < rows; i++ )
+ {
+ for ( j = 0; j < width; j += 1 )
+ FT_TRACE7(( " %3u", topleft[i * pitch + j] ));
+ FT_TRACE7(( "\n" ));
+ }
}
+ FT_TRACE7(( "Netpbm image: end\n" ));
}
#undef FT_COMPONENT
@@ -4437,7 +4739,7 @@
if ( !clazz )
return FT_THROW( Invalid_Argument );
- /* check freetype version */
+ /* check FreeType version */
if ( clazz->module_requires > FREETYPE_VER_FIXED )
return FT_THROW( Invalid_Version );
@@ -4861,10 +5163,6 @@
goto Fail;
#endif
- /* we don't use raster_pool anymore. */
- library->raster_pool_size = 0;
- library->raster_pool = NULL;
-
library->version_major = FREETYPE_MAJOR;
library->version_minor = FREETYPE_MINOR;
library->version_patch = FREETYPE_PATCH;
@@ -4879,9 +5177,9 @@
#ifdef FT_CONFIG_OPTION_PIC
Fail:
ft_pic_container_destroy( library );
-#endif
FT_FREE( library );
return error;
+#endif
}