[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[freetype2] master 27fee7f 8/8: [sfnt, truetype] Always provide default
From: |
Werner LEMBERG |
Subject: |
[freetype2] master 27fee7f 8/8: [sfnt, truetype] Always provide default instance. |
Date: |
Mon, 6 Mar 2017 14:47:02 -0500 (EST) |
branch: master
commit 27fee7f8c6ae75e066b5a23472b33925c6e8b1e0
Author: Werner Lemberg <address@hidden>
Commit: Werner Lemberg <address@hidden>
[sfnt, truetype] Always provide default instance.
As documented in the OpenType specification, an entry for the
default instance may be omitted in the named instance table. In
particular this means that even if there is no named instance table
in the font we actually do have a named instance, namely the default
instance.
For consistency, we always want the default instance in our list of
named instances. If it is missing, we try to synthesize it.
* src/sfnt/sfobjs.c (sfnt_init_face): Check whether the default
instance is in the table of named instances. Otherwise adjust
number of instances.
* src/truetype/ttgxvar.c: Include FT_TRUETYPE_IDS_H.
(TT_Get_MM_Var): Use `face->root.style_flags' as the number of named
instances.
Sythesize a named instance entry if necessary.
(tt_done_blend): Free `normalized_stylecoords'.
---
ChangeLog | 23 ++++++++++++
src/sfnt/sfobjs.c | 63 +++++++++++++++++++++++++++++++++
src/truetype/ttgxvar.c | 95 ++++++++++++++++++++++++++++++++++++++++----------
3 files changed, 162 insertions(+), 19 deletions(-)
diff --git a/ChangeLog b/ChangeLog
index 3bbfe42..3074bcb 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,26 @@
+2017-03-06 Werner Lemberg <address@hidden>
+
+ [sfnt, truetype] Always provide default instance.
+
+ As documented in the OpenType specification, an entry for the
+ default instance may be omitted in the named instance table. In
+ particular this means that even if there is no named instance table
+ in the font we actually do have a named instance, namely the default
+ instance.
+
+ For consistency, we always want the default instance in our list of
+ named instances. If it is missing, we try to synthesize it.
+
+ * src/sfnt/sfobjs.c (sfnt_init_face): Check whether the default
+ instance is in the table of named instances. Otherwise adjust
+ number of instances.
+
+ * src/truetype/ttgxvar.c: Include FT_TRUETYPE_IDS_H.
+ (TT_Get_MM_Var): Use `face->root.style_flags' as the number of named
+ instances.
+ Sythesize a named instance entry if necessary.
+ (tt_done_blend): Free `normalized_stylecoords'.
+
2017-03-05 Werner Lemberg <address@hidden>
[sfnt] Remove redundant code.
diff --git a/src/sfnt/sfobjs.c b/src/sfnt/sfobjs.c
index 4cc3e3f..51be1c2 100644
--- a/src/sfnt/sfobjs.c
+++ b/src/sfnt/sfobjs.c
@@ -856,6 +856,7 @@
FT_Parameter* params )
{
FT_Error error;
+ FT_Memory memory = face->root.memory;
FT_Library library = face->root.driver->root.library;
SFNT_Service sfnt;
FT_Int face_index;
@@ -954,6 +955,9 @@
FT_Int instance_index;
+ FT_Byte* default_values = NULL;
+ FT_Byte* instance_values = NULL;
+
face->is_default_instance = 1;
@@ -999,6 +1003,65 @@
if ( !face->goto_table( face, TTAG_CFF, stream, 0 ) )
num_instances = 0;
+ /*
+ * As documented in the OpenType specification, an entry for the
+ * default instance may be omitted in the named instance table. In
+ * particular this means that even if there is no named instance
+ * table in the font we actually do have a named instance, namely the
+ * default instance.
+ *
+ * For consistency, we always want the default instance in our list
+ * of named instances. If it is missing, we try to synthesize it
+ * later on. Here, we have to adjust `num_instances' accordingly.
+ */
+
+ if ( !( FT_ALLOC( default_values, num_axes * 2 ) ||
+ FT_ALLOC( instance_values, num_axes * 2 ) ) )
+ {
+ /* the current stream position is 16 bytes after the table start */
+ FT_ULong array_start = FT_STREAM_POS() - 16 + offset;
+ FT_ULong default_value_offset, instance_offset;
+
+ FT_Byte* p;
+ FT_UInt i;
+
+
+ default_value_offset = array_start + 8;
+ p = default_values;
+
+ for ( i = 0; i < num_axes; i++ )
+ {
+ (void)FT_STREAM_READ_AT( default_value_offset, p, 2 );
+
+ default_value_offset += axis_size;
+ p += 2;
+ }
+
+ instance_offset = array_start + axis_size * num_axes + 4;
+
+ for ( i = 0; i < num_instances; i++ )
+ {
+ (void)FT_STREAM_READ_AT( instance_offset,
+ instance_values,
+ num_axes * 2 );
+
+ if ( !ft_memcmp( default_values, instance_values, num_axes * 2 ) )
+ break;
+
+ instance_offset += instance_size;
+ }
+
+ if ( i == num_instances )
+ {
+ /* no default instance in named instance table; */
+ /* we thus have to synthesize it */
+ num_instances++;
+ }
+ }
+
+ FT_FREE( default_values );
+ FT_FREE( instance_values );
+
/* instance indices in `face_instance_index' start with index 1, */
/* thus `>' and not `>=' */
if ( instance_index > num_instances )
diff --git a/src/truetype/ttgxvar.c b/src/truetype/ttgxvar.c
index 50da2ea..fa614ca 100644
--- a/src/truetype/ttgxvar.c
+++ b/src/truetype/ttgxvar.c
@@ -45,6 +45,7 @@
#include FT_INTERNAL_STREAM_H
#include FT_INTERNAL_SFNT_H
#include FT_TRUETYPE_TAGS_H
+#include FT_TRUETYPE_IDS_H
#include FT_MULTIPLE_MASTERS_H
#include FT_LIST_H
@@ -1930,15 +1931,17 @@
FT_ULong table_len;
FT_Error error = FT_Err_Ok;
FT_ULong fvar_start;
- FT_Int i, j;
+ FT_UInt i, j;
FT_MM_Var* mmvar = NULL;
FT_Fixed* next_coords;
FT_Fixed* nsc;
FT_String* next_name;
FT_Var_Axis* a;
+ FT_Fixed* c;
FT_Var_Named_Style* ns;
GX_FVar_Head fvar_head;
FT_Bool usePsName;
+ FT_UInt num_instances;
static const FT_Frame_Field fvar_fields[] =
{
@@ -2019,12 +2022,18 @@
if ( FT_NEW( face->blend ) )
goto Exit;
- /* cannot overflow 32-bit arithmetic because of the validity check */
+ /* `num_instances' holds the number of all named instances, */
+ /* including the default instance which might be missing */
+ /* in fvar's table of named instances */
+ num_instances = face->root.style_flags >> 16;
+
+ /* cannot overflow 32-bit arithmetic because of the size limits */
+ /* used in the `fvar' table validity check in `sfnt_init_face' */
face->blend->mmvar_len =
sizeof ( FT_MM_Var ) +
fvar_head.axisCount * sizeof ( FT_Var_Axis ) +
- fvar_head.instanceCount * sizeof ( FT_Var_Named_Style ) +
- fvar_head.instanceCount * fvar_head.axisCount * sizeof ( FT_Fixed ) +
+ num_instances * sizeof ( FT_Var_Named_Style ) +
+ num_instances * fvar_head.axisCount * sizeof ( FT_Fixed ) +
5 * fvar_head.axisCount;
if ( FT_ALLOC( mmvar, face->blend->mmvar_len ) )
@@ -2041,15 +2050,15 @@
/* may have a different number of designs */
/* (or tuples, as called by Apple) */
mmvar->num_namedstyles =
- fvar_head.instanceCount;
+ num_instances;
mmvar->axis =
(FT_Var_Axis*)&( mmvar[1] );
mmvar->namedstyle =
(FT_Var_Named_Style*)&( mmvar->axis[fvar_head.axisCount] );
next_coords =
- (FT_Fixed*)&( mmvar->namedstyle[fvar_head.instanceCount] );
- for ( i = 0; i < fvar_head.instanceCount; i++ )
+ (FT_Fixed*)&( mmvar->namedstyle[num_instances] );
+ for ( i = 0; i < num_instances; i++ )
{
mmvar->namedstyle[i].coords = next_coords;
next_coords += fvar_head.axisCount;
@@ -2109,17 +2118,14 @@
FT_TRACE5(( "\n" ));
- if ( fvar_head.instanceCount )
- {
- /* named instance coordinates are stored as design coordinates; */
- /* we have to convert them to normalized coordinates also */
- if ( FT_NEW_ARRAY( face->blend->normalized_stylecoords,
- fvar_head.axisCount * fvar_head.instanceCount ) )
- goto Exit;
+ /* named instance coordinates are stored as design coordinates; */
+ /* we have to convert them to normalized coordinates also */
+ if ( FT_NEW_ARRAY( face->blend->normalized_stylecoords,
+ fvar_head.axisCount * num_instances ) )
+ goto Exit;
- if ( !face->blend->avar_checked )
- ft_var_load_avar( face );
- }
+ if ( fvar_head.instanceCount && !face->blend->avar_checked )
+ ft_var_load_avar( face );
ns = mmvar->namedstyle;
nsc = face->blend->normalized_stylecoords;
@@ -2133,8 +2139,9 @@
ns->strid = FT_GET_USHORT();
(void) /* flags = */ FT_GET_USHORT();
- for ( j = 0; j < fvar_head.axisCount; j++ )
- ns->coords[j] = FT_GET_LONG();
+ c = ns->coords;
+ for ( j = 0; j < fvar_head.axisCount; j++, c++ )
+ *c = FT_GET_LONG();
if ( usePsName )
ns->psid = FT_GET_USHORT();
@@ -2148,6 +2155,55 @@
FT_FRAME_EXIT();
}
+ if ( num_instances != fvar_head.instanceCount )
+ {
+ SFNT_Service sfnt = (SFNT_Service)face->sfnt;
+
+ FT_Int found, win, apple;
+
+
+ /* the default instance is missing in array the */
+ /* of named instances; try to synthesize an entry */
+ found = sfnt->get_name_id( face,
+ TT_NAME_ID_TYPOGRAPHIC_SUBFAMILY,
+ &win,
+ &apple );
+ if ( !found )
+ found = sfnt->get_name_id( face,
+ TT_NAME_ID_FONT_SUBFAMILY,
+ &win,
+ &apple );
+
+ if ( found )
+ {
+ FT_Int strid = win >= 0 ? win : apple;
+
+
+ found = sfnt->get_name_id( face,
+ TT_NAME_ID_PS_NAME,
+ &win,
+ &apple );
+ if ( found )
+ {
+ FT_Int psid = win >= 0 ? win : apple;
+
+
+ FT_TRACE5(( "TT_Get_MM_Var:"
+ " Adding default instance to named instances\n" ));
+
+ ns = &mmvar->namedstyle[fvar_head.instanceCount];
+
+ ns->strid = strid;
+ ns->psid = psid;
+
+ a = mmvar->axis;
+ c = ns->coords;
+ for ( j = 0; j < fvar_head.axisCount; j++, a++, c++ )
+ *c = a->def;
+ }
+ }
+ }
+
ft_var_load_mvar( face );
}
@@ -3528,6 +3584,7 @@
num_axes = blend->mmvar->num_axis;
FT_FREE( blend->normalizedcoords );
+ FT_FREE( blend->normalized_stylecoords );
FT_FREE( blend->mmvar );
if ( blend->avar_segment )
[Prev in Thread] |
Current Thread |
[Next in Thread] |
- [freetype2] master 27fee7f 8/8: [sfnt, truetype] Always provide default instance.,
Werner LEMBERG <=