[Top][All Lists]
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[ft-devel] a flag making FT_Open_Face() to use fallback family name
From: |
mpsuzuki |
Subject: |
[ft-devel] a flag making FT_Open_Face() to use fallback family name |
Date: |
Fri, 27 Aug 2010 00:00:32 +0900 |
Sorry for posting so many.
In previous post, I proposed a patch to expose the tricky
font list to FT2 client, to check if the font is tricky by
its name before the creation of FT_Face object:
http://lists.gnu.org/archive/html/freetype-devel/2010-08/msg00018.html
The reason why the name only without font data is that
Type42/Type11 TrueType font may lack "name" table (and FT2
cannot know the font name from the font file).
I've tried another idea to reduce the additional code size:
an introduction of new flag for FT_Open_Face(), to pass
a fallback family name. By using the flag, FT_Open_Face()
uses the fallback family name (taken from the optional
parameters) when sfnt data lacks "name" table.
Or, should I use FT_Face_Attach function for TrueType?
At present, the feature is only used by PS Type1 font to
add the metric infos stored in external AFM/PFM file.
It may be possible (in technical meaning) to write a function
to add/overwrite the information taken from PDF font
descriptor stream (e.g. PS font name, StemV, Ascent, Descent,
ItalicAngle, CapHeight, FontBBox etc). However, the attempt
to overwrite something in TrueType is not PDF-specific issue,
so the usage of the attach feature must be considered well.
If you think FT_Face_Attach is better than passing fallback
family name flag to FT_Open_Face(), please ignore following
part of this post, and give me short comment.
Regards,
mpsuzuki
==========================================================
The patch to add fallback family name feature is following:
diff --git a/include/freetype/ftsnames.h b/include/freetype/ftsnames.h
index 485e4e1..7e95229 100644
--- a/include/freetype/ftsnames.h
+++ b/include/freetype/ftsnames.h
@@ -189,6 +189,22 @@ FT_BEGIN_HEADER
*/
#define FT_PARAM_TAG_IGNORE_PREFERRED_SUBFAMILY FT_MAKE_TAG( 'i', 'g', 'p',
's' )
+
+ /***************************************************************************
+ *
+ * @constant:
+ * FT_PARAM_TAG_FALLBACK_NAME_FAMILY
+ *
+ * @description:
+ * A constant used as the tag of @FT_Parameter structures to specify
+ * a fallback family name. The embedded TrueType font in Type42 or
+ * Type11 format may lack the name table in its sfnt stream. To make
+ * FT_Face object with valid family name for such fonts, this option
+ * should be used.
+ *
+ */
+#define FT_PARAM_TAG_FALLBACK_NAME_FAMILY FT_MAKE_TAG( 'f', 'b', 'n', 'f' )
+
/* */
diff --git a/src/sfnt/sfobjs.c b/src/sfnt/sfobjs.c
index 6e35e2d..5e64046 100644
--- a/src/sfnt/sfobjs.c
+++ b/src/sfnt/sfobjs.c
@@ -530,6 +530,7 @@
FT_Bool is_apple_sbit;
FT_Bool ignore_preferred_family = FALSE;
FT_Bool ignore_preferred_subfamily = FALSE;
+ FT_String* fallback_name_family = NULL;
SFNT_Service sfnt = (SFNT_Service)face->sfnt;
@@ -543,10 +544,25 @@
for ( i = 0; i < num_params; i++ )
{
- if ( params[i].tag == FT_PARAM_TAG_IGNORE_PREFERRED_FAMILY )
- ignore_preferred_family = TRUE;
- else if ( params[i].tag == FT_PARAM_TAG_IGNORE_PREFERRED_SUBFAMILY )
- ignore_preferred_subfamily = TRUE;
+ switch( params[i].tag )
+ {
+ case FT_PARAM_TAG_IGNORE_PREFERRED_FAMILY:
+ ignore_preferred_family = TRUE;
+ break;
+ case FT_PARAM_TAG_IGNORE_PREFERRED_SUBFAMILY:
+ ignore_preferred_subfamily = TRUE;
+ break;
+ case FT_PARAM_TAG_FALLBACK_NAME_FAMILY:
+ fallback_name_family = (FT_String*)params[i].data;
+ break;
+ default:
+ FT_TRACE2(( "sfnt_load_face: ignore unknown FT_Param"
+ " tagged [%c%c%c%c]\n",
+ ( params[i].tag >> 24 ) & 0xFF,
+ ( params[i].tag >> 16 ) & 0xFF,
+ ( params[i].tag >> 8 ) & 0xFF,
+ ( params[i].tag ) & 0xFF ));
+ }
}
}
@@ -766,6 +782,21 @@
GET_NAME( FONT_SUBFAMILY, &face->root.style_name );
}
+ /* fallback for empty names */
+ {
+ FT_Memory memory = face->root.stream->memory;
+ FT_UInt len;
+
+
+ if ( !face->root.family_name && fallback_name_family )
+ {
+ len = ft_strlen( fallback_name_family );
+ if ( !FT_NEW_ARRAY( face->root.family_name, len + 1 ) )
+ ft_memcpy( face->root.family_name, fallback_name_family, len + 1 );
+ }
+ /* subfamily/styles are needed? */
+ }
+
/* now set up root fields */
{
FT_Face root = &face->root;
-------------------------------------------------------------------
Maybe it is not easy to understand how to use this.
The patch for freetype2-demos attached to the end of this
message. It modifies ftdump & ftview and add "-F" option
to specify the fallback family name. It works aslike:
$ ./ftdump ./dell440_037-000.ttf
There is 1 face in this file.
----- Face number: 0 -----
font name entries
family: (null)
style: (null)
postscript: UNAVAILABLE
...
$ ./ftdump -F MingLiU ./dell440_037-000.ttf
There is 1 face in this file.
----- Face number: 0 -----
font name entries
family: MingLiU
style: (null)
postscript: UNAVAILABLE
...
Some people will wonder "so what? what is the advantage
of such joking feature?". Please try ftview. If you
execute ftview for dell440_037-000.ttf without fallback
family name, the hinting switch will work - if hinted,
the glyph is correct, if unhinted, the glyph is broken.
Maybe it sounds odd, this is NOT what the residents in
the world of flooding MingLiU. What they (including me)
expect is: even if FT_New_Face() is invoked with FT_LOAD_NO_HINTING,
the hinter should be enabled. So the hinting switch changes
nothing for MingLiU is expected. If you try genuine MingLiU
not subsetted, you will find such behaviour. This hook is
realized by the tricky font list.
Then, if you execute with fallback family name,
$ ./ftview -F MingLiU 40 ./dell440_037-000.ttf
You will find hinting is always enabled and the switch
does not change anything. This is the behaviour that
the residents in the world of flooding MingLiU expect.
The patch for freetype2-demos is following:
diff --git a/src/ftcommon.c b/src/ftcommon.c
index 8a60c15..938dace 100644
--- a/src/ftcommon.c
+++ b/src/ftcommon.c
@@ -17,6 +17,7 @@
#include FT_CACHE_H
#include FT_CACHE_MANAGER_H
+#include FT_SFNT_NAMES_H
#include FT_BITMAP_H
#include "common.h"
@@ -191,6 +192,34 @@
};
+ static FT_Error
+ ft_new_face_with_params( FT_Library library,
+ const char* pathname,
+ FT_UInt face_index,
+ FT_UInt num_params,
+ FT_Parameter* params,
+ FT_Face* aface )
+ {
+ FT_Error error = FT_Err_Invalid_Argument;
+ FT_Open_Args args;
+
+ if ( !pathname )
+ return error;
+
+ args.flags = FT_OPEN_PATHNAME;
+ args.pathname = (char*)pathname;
+ args.stream = NULL;
+
+ if ( num_params > 0 )
+ {
+ args.flags |= FT_OPEN_PARAMS;
+ args.num_params = num_params;
+ args.params = params;
+ }
+ return FT_Open_Face( library, &args, face_index, aface );
+ }
+
+
/*************************************************************************/
/* */
/* The face requester is a function provided by the client application */
@@ -206,6 +235,8 @@
FT_Face* aface )
{
PFont font = (PFont)face_id;
+ FT_Parameter param = { FT_PARAM_TAG_FALLBACK_NAME_FAMILY,
+ font->fallback_name_family };
FT_UNUSED( request_data );
@@ -216,10 +247,12 @@
font->face_index,
aface );
else
- error = FT_New_Face( lib,
- font->filepathname,
- font->face_index,
- aface );
+ error = ft_new_face_with_params( lib,
+ font->filepathname,
+ font->face_index,
+ 1, ¶m,
+ aface );
+
if ( !error )
{
char* suffix;
@@ -344,11 +377,13 @@
FT_Error
- FTDemo_Install_Font( FTDemo_Handle* handle,
- const char* filepath )
+ FTDemo_Install_Font_With_Params( FTDemo_Handle* handle,
+ const char* filepath,
+ FT_UInt num_params,
+ FT_Parameter* params )
{
static char filename[1024 + 5];
- int i, len, num_faces;
+ int i, j, len, num_faces;
FT_Face face;
@@ -359,8 +394,8 @@
strncpy( filename, filepath, len );
filename[len] = 0;
- error = FT_New_Face( handle->library, filename, 0, &face );
-
+ error = ft_new_face_with_params( handle->library, filename, 0,
+ num_params, params, &face );
#ifndef macintosh
/* could not open the file directly; we will now try various */
/* suffixes like `.ttf' or `.pfb' */
@@ -390,7 +425,8 @@
/* try with current suffix */
strcpy( p, suffix[0] );
- error = FT_New_Face( handle->library, filename, 0, &face );
+ error = ft_new_face_with_params( handle->library, filename, 0,
+ num_params, params, &face );
if ( !error )
{
found = 1;
@@ -414,7 +450,8 @@
if ( i > 0 )
{
- error = FT_New_Face( handle->library, filename, i, &face );
+ error = ft_new_face_with_params( handle->library, filename, i,
+ num_params, params, &face );
if ( error )
continue;
}
@@ -434,6 +471,14 @@
font->filepathname = (char*)malloc( strlen( filename ) + 1 );
strcpy( (char*)font->filepathname, filename );
+ font->fallback_name_family = NULL;
+ for ( j = 0; j < num_params; j++ )
+ if ( params[j].tag == FT_PARAM_TAG_FALLBACK_NAME_FAMILY )
+ {
+ font->fallback_name_family = (char*)malloc( strlen( params[j].data )
);
+ strcpy( (char*)font->fallback_name_family, params[j].data );
+ }
+
font->face_index = i;
font->cmap_index = face->charmap ? FT_Get_Charmap_Index( face->charmap )
: 0;
@@ -520,6 +565,14 @@
}
+ FT_Error
+ FTDemo_Install_Font( FTDemo_Handle* handle,
+ const char* filepath )
+ {
+ return FTDemo_Install_Font_With_Params( handle, filepath, 0, NULL );
+ }
+
+
void
FTDemo_Set_Current_Font( FTDemo_Handle* handle,
PFont font )
diff --git a/src/ftcommon.h b/src/ftcommon.h
index e6ce02f..10875c2 100644
--- a/src/ftcommon.h
+++ b/src/ftcommon.h
@@ -117,6 +117,8 @@
void* file_address; /* for preloaded files */
size_t file_size;
+ /* FT_Face object may be recreated, so info for recreation should be
stored in PFont */
+ FT_String* fallback_name_family;
} TFont, *PFont;
enum {
@@ -206,6 +208,13 @@
/* install a font */
FT_Error
+ FTDemo_Install_Font_With_Params( FTDemo_Handle* handle,
+ const char* filepath,
+ FT_UInt num_params,
+ FT_Parameter* params );
+
+
+ FT_Error
FTDemo_Install_Font( FTDemo_Handle* handle,
const char* filepath );
diff --git a/src/ftdump.c b/src/ftdump.c
index 3bb7fc0..d35e2d4 100644
--- a/src/ftdump.c
+++ b/src/ftdump.c
@@ -36,6 +36,7 @@
int debug = 0;
int trace_level = 0;
int name_tables = 0;
+ char* fallback_name_family = NULL;
/* PanicZ */
@@ -73,6 +74,7 @@
fprintf( stderr, " -l level trace level for debug information\n" );
# endif
#endif
+ fprintf( stderr, " -F fallback family name\n" );
fprintf( stderr, " -n print SFNT name tables\n" );
fprintf( stderr, " -v be verbose\n" );
fprintf( stderr, "\n" );
@@ -557,7 +559,7 @@
while ( 1 )
{
- option = getopt( argc, argv, "dl:nv" );
+ option = getopt( argc, argv, "dl:F:nv" );
if ( option == -1 )
break;
@@ -574,6 +576,10 @@
usage( execname );
break;
+ case 'F':
+ fallback_name_family = optarg;
+ break;
+
case 'n':
name_tables = 1;
break;
@@ -666,7 +672,30 @@
for ( i = 0; i < num_faces; i++ )
{
+#if 0
error = FT_New_Face( library, filename, i, &face );
+#else
+ {
+ error = FT_Err_Invalid_Argument;
+ if ( filename[0] )
+ {
+ FT_Open_Args args;
+ FT_Parameter param;
+
+
+ args.flags = FT_OPEN_PATHNAME | FT_OPEN_PARAMS;
+ args.pathname = (char*)filename;
+ args.stream = NULL;
+
+ param.tag = FT_PARAM_TAG_FALLBACK_NAME_FAMILY;
+ param.data = fallback_name_family;
+ args.params = ¶m;
+ args.num_params = 1;
+
+ error = FT_Open_Face( library, &args, i, &face );
+ }
+ }
+#endif
if ( error )
PanicZ( "Could not open face." );
diff --git a/src/ftview.c b/src/ftview.c
index 42ed67c..d132e36 100644
--- a/src/ftview.c
+++ b/src/ftview.c
@@ -26,6 +26,7 @@
#include FT_STROKER_H
#include FT_SYNTHESIS_H
#include FT_LCD_FILTER_H
+#include FT_SFNT_NAMES_H
#define MAXPTSIZE 500 /* dtp */
#define HEADER_HEIGHT 8
@@ -92,11 +93,12 @@
int use_custom_lcd_filter;
unsigned char filter_weights[5];
int fw_index;
+ char* fallback_name_family;
} status = { RENDER_MODE_ALL, FT_ENCODING_NONE, 72, 48, -1,
1.0, 0.04, 0.22,
0, 0, 0, 0, 0, NULL, { 0 }, 0, 0,
- 0, "\x10\x40\x70\x40\x10", 2 };
+ 0, "\x10\x40\x70\x40\x10", 2, NULL };
static FTDemo_Display* display;
@@ -1247,6 +1249,7 @@
fprintf( stderr, " `.afm' or `.pfm').\n" );
fprintf( stderr, "\n" );
fprintf( stderr, " -r R Use resolution R dpi (default: 72 dpi).\n"
);
+ fprintf( stderr, " -F name Specify fallback family name.\n" );
fprintf( stderr, " -f index Specify first index to display.\n" );
fprintf( stderr, " -e enc Specify encoding tag (default: no
encoding).\n" );
fprintf( stderr, " -D Dump cache usage statistics.\n" );
@@ -1272,7 +1275,7 @@
while ( 1 )
{
- option = getopt( *argc, *argv, "Dde:f:L:l:r:m:p" );
+ option = getopt( *argc, *argv, "Dde:F:f:L:l:r:m:p" );
if ( option == -1 )
break;
@@ -1291,6 +1294,10 @@
status.encoding = FTDemo_Make_Encoding_Tag( optarg );
break;
+ case 'F':
+ status.fallback_name_family = optarg;
+ break;
+
case 'f':
status.Num = atoi( optarg );
break;
@@ -1386,7 +1393,14 @@
FTDemo_Set_Preload( handle, 1 );
for ( ; argc > 0; argc--, argv++ )
- FTDemo_Install_Font( handle, argv[0] );
+ {
+ FT_Parameter param;
+
+
+ param.tag = FT_PARAM_TAG_FALLBACK_NAME_FAMILY;
+ param.data = status.fallback_name_family;
+ FTDemo_Install_Font_With_Params( handle, argv[0], 1, ¶m );
+ }
if ( handle->num_fonts == 0 )
Fatal( "could not find/open any font file" );
dell440_037-000.ttf.bz2
Description: Binary data