* include/freetype/config/ftoption.h,

include/freetype/config/ftstdlib.h,
        include/freetype/internal/tttypes.h,
        src/sfnt/Jamfile, src/sfnt/rules.mk, src/sfnt/sfdriver.c,
        src/sfnt/ttbdf.h, src/sfnt/ttbdf.c, src/sfnt/sfobjs.c:

        Added support for an embedded 'BDF ' table within SFNT-based
        bitmap font files. This is used to store atoms & properties from
        the original BDF fonts that were used to generate the font file.

        the feature is controled by TT_CONFIG_OPTION_BDF within 'ftoption.h'
        and is used to implement FT_Get_BDF_Property for these font files.

        At the moment, this is still experimental, the BDF table format isn't
        cast into stone yet.
This commit is contained in:
David Turner 2005-12-14 20:38:15 +00:00
parent 8def3c897f
commit 89a2a4b531
12 changed files with 428 additions and 4 deletions

View File

@ -12,6 +12,8 @@
same location than other generated objects (i.e. within the 'objs'
directory of the current dir)
* src/sfnt/
2005-12-07 Werner Lemberg <wl@gnu.org>
* src/sfnt/sfobjc.c (sfnt_init_face): Move tag check to...

View File

@ -101,9 +101,7 @@ FT_BEGIN_HEADER
/* */
/* FreeType now handles font files that have been compressed with the */
/* 'compress' program. This is mostly used to parse many of the PCF */
/* files that come with various X11 distributions. The implementation */
/* uses NetBSD's `zopen' to partially uncompress the file on the fly */
/* (see src/lzw/ftgzip.c). */
/* files that come with various X11 distributions. */
/* */
/* Define this macro if you want to enable this `feature'. */
/* */
@ -493,6 +491,13 @@ FT_BEGIN_HEADER
#define TT_CONFIG_OPTION_GX_VAR_SUPPORT
/*************************************************************************/
/* */
/* Define TT_CONFIG_OPTION_BDF if upi want to include support for */
/* an embedded 'BDF' table within SFNT-based bitmap formats. */
/* */
#define TT_CONFIG_OPTION_BDF
/*************************************************************************/
/*************************************************************************/
/**** ****/
@ -547,6 +552,7 @@ FT_BEGIN_HEADER
/* */
#undef T1_CONFIG_OPTION_NO_MM_SUPPORT
/* */
/*

View File

@ -92,6 +92,7 @@
#define ft_memcpy memcpy
#define ft_memmove memmove
#define ft_memset memset
#define ft_memchr memchr
#define ft_strcat strcat
#define ft_strcmp strcmp
#define ft_strcpy strcpy

View File

@ -843,6 +843,68 @@ FT_BEGIN_HEADER
typedef struct GX_BlendRec_ *GX_Blend;
#endif
/*************************************************************************/
/*************************************************************************/
/*************************************************************************/
/*** ***/
/*** ***/
/*** EMBEDDED BDF PROPERTIES TABLE SUPPORT ***/
/*** ***/
/*** ***/
/*************************************************************************/
/*************************************************************************/
/*************************************************************************/
/* these types are used to support a 'BDF' table that isn't part of the
* official TrueType specification. It is mainly used in SFNT-based bitmap
* fonts that were generated from a set of BDF fonts
*
* the format of the table is the following:
*
* USHORT version 'BDF' table version number, should be 0x0001
* USHORT strikeCount number of strikes (bitmap sizes) in this table
* ULONG stringTable offset (froms start of BDF table) to string table
*
* followed by an array of 'strikeCount' descriptors that look like:
*
* USHORT ppem vertical pixels per EM for this strike
* USHORT numItems number of items for this strike (properties and
* atoms), max is 255
*
* this array is followed by 'strikeCount' value sets. Each "value set"
* is an array of 'numItems' items that look like the following:
*
* ULONG item_name offset in string table to item name
* USHORT item_type 0 => string (e.g. COMMENT)
* 1 => atom (e.g. FONT or even SIZE)
* 2 => int32
* 3 => uint32
* 0x10 => flag for properties, ored with above values
*
* ULONG item_value for strings => offset in string table without
* the corresponding double quotes
*
* atoms => offset in string table
*
* integers => direct value
*
* all strings in the string table are 8-bit, zero-terminated
*/
#ifdef TT_CONFIG_OPTION_BDF
typedef struct TT_BDFRec_
{
FT_Byte* table;
FT_Byte* table_end;
FT_Byte* strings;
FT_UInt32 strings_size;
FT_UInt num_strikes;
FT_Bool loaded;
} TT_BDFRec, *TT_BDF;
#endif /* TT_CONFIG_OPTION_BDF */
/*************************************************************************/
/*************************************************************************/
@ -1342,6 +1404,10 @@ FT_BEGIN_HEADER
GX_Blend blend;
#endif
#ifdef TT_CONFIG_OPTION_BDF
TT_BDFRec bdf;
#endif /* TT_CONFIG_OPTION_BDF */
/***********************************************************************/
/* */
/* Other tables or fields. This is used by derivative formats like */

View File

@ -36,6 +36,7 @@ FT_BEGIN_HEADER
#define TTAG_avar FT_MAKE_TAG( 'a', 'v', 'a', 'r' )
#define TTAG_BASE FT_MAKE_TAG( 'B', 'A', 'S', 'E' )
#define TTAG_bdat FT_MAKE_TAG( 'b', 'd', 'a', 't' )
#define TTAG_BDF FT_MAKE_TAG( 'B', 'D', 'F', ' ' )
#define TTAG_bhed FT_MAKE_TAG( 'b', 'h', 'e', 'd' )
#define TTAG_bloc FT_MAKE_TAG( 'b', 'l', 'o', 'c' )
#define TTAG_bsln FT_MAKE_TAG( 'b', 's', 'l', 'n' )

View File

@ -16,7 +16,7 @@ SubDir FT2_TOP $(FT2_SRC_DIR) sfnt ;
if $(FT2_MULTI)
{
_sources = sfobjs sfdriver ttcmap ttpost ttload ttsbit ttkern ;
_sources = sfobjs sfdriver ttcmap ttpost ttload ttsbit ttkern ttbdf ;
}
else
{

View File

@ -30,6 +30,7 @@ SFNT_DRV_SRC := $(SFNT_DIR)/ttload.c \
$(SFNT_DIR)/ttsbit.c \
$(SFNT_DIR)/ttpost.c \
$(SFNT_DIR)/ttkern.c \
$(SFNT_DIR)/ttbdf.c \
$(SFNT_DIR)/sfobjs.c \
$(SFNT_DIR)/sfdriver.c

View File

@ -34,6 +34,11 @@
#include "ttpost.h"
#endif
#ifdef TT_CONFIG_OPTION_BDF
#include "ttbdf.h"
#include FT_SERVICE_BDF_H
#endif
#include "ttcmap.h"
#include "ttkern.h"
@ -293,6 +298,51 @@
(TT_CMap_Info_GetFunc)tt_get_cmap_info
};
#ifdef TT_CONFIG_OPTION_BDF
static FT_Error
sfnt_get_charset_id( TT_Face face,
const char* *acharset_encoding,
const char* *acharset_registry )
{
BDF_PropertyRec encoding, registry;
FT_Error error;
/* XXX: I don't know if this is correct, since tt_face_find_bdf_prop
* will only return something correct if we have previously
* selected a size that is listed in the BDF table.
* should we change the BDF table format to include single
* offsets for "CHARSET_REGISTRY" and "CHARSET_ENCODING" ?
*/
error = tt_face_find_bdf_prop( face, "CHARSET_REGISTRY", &registry );
if ( !error )
{
error = tt_face_find_bdf_prop( face, "CHARSET_ENCODING", &encoding );
if ( !error )
{
if ( registry.type == BDF_PROPERTY_TYPE_ATOM &&
encoding.type == BDF_PROPERTY_TYPE_ATOM )
{
*acharset_encoding = encoding.u.atom;
*acharset_registry = registry.u.atom;
}
else
error = FT_Err_Invalid_Argument;
}
}
return error;
}
static const FT_Service_BDFRec sfnt_service_bdf =
{
(FT_BDF_GetCharsetIdFunc) sfnt_get_charset_id,
(FT_BDF_GetPropertyFunc) tt_face_find_bdf_prop,
};
#endif /* TT_CONFIG_OPTION_BDF */
/*
* SERVICE LIST
@ -305,6 +355,9 @@
{ FT_SERVICE_ID_POSTSCRIPT_FONT_NAME, &sfnt_service_ps_name },
#ifdef TT_CONFIG_OPTION_POSTSCRIPT_NAMES
{ FT_SERVICE_ID_GLYPH_DICT, &sfnt_service_glyph_dict },
#endif
#ifdef TT_CONFIG_OPTION_BDF
{ FT_SERVICE_ID_BDF, &sfnt_service_bdf },
#endif
{ FT_SERVICE_ID_TT_CMAP, &tt_service_get_cmap_info },

View File

@ -33,5 +33,8 @@
#include "ttpost.c"
#endif
#ifdef TT_CONFIG_OPTION_BDF
#include "ttbdf.c"
#endif
/* END */

View File

@ -27,6 +27,9 @@
#include FT_SERVICE_POSTSCRIPT_CMAPS_H
#include "sferrors.h"
#ifdef TT_CONFIG_OPTION_BDF
#include "ttbdf.h"
#endif
/*************************************************************************/
/* */
@ -752,6 +755,11 @@
sfnt->free_sbits( face );
}
#ifdef TT_CONFIG_OPTION_BDF
/* freeing the embedded BDF properties */
tt_face_free_bdf_props( face );
#endif
/* freeing the kerning table */
tt_face_done_kern( face );

237
src/sfnt/ttbdf.c Normal file
View File

@ -0,0 +1,237 @@
/***************************************************************************/
/* */
/* ttbdf.c */
/* */
/* TrueType and OpenType embedded BDF properties (body). */
/* */
/* Copyright 2005 by */
/* David Turner, Robert Wilhelm, and Werner Lemberg. */
/* */
/* This file is part of the FreeType project, and may only be used, */
/* modified, and distributed under the terms of the FreeType project */
/* license, LICENSE.TXT. By continuing to use, modify, or distribute */
/* this file you indicate that you have read the license and */
/* understand and accept it fully. */
/* */
/***************************************************************************/
#include <ft2build.h>
#include FT_INTERNAL_DEBUG_H
#include FT_INTERNAL_STREAM_H
#include FT_TRUETYPE_TAGS_H
#include "ttbdf.h"
#include "sferrors.h"
#ifdef TT_CONFIG_OPTION_BDF
/*************************************************************************/
/* */
/* The macro FT_COMPONENT is used in trace mode. It is an implicit */
/* parameter of the FT_TRACE() and FT_ERROR() macros, used to print/log */
/* messages during execution. */
/* */
#undef FT_COMPONENT
#define FT_COMPONENT trace_ttbdf
FT_LOCAL_DEF( void )
tt_face_free_bdf_props( TT_Face face )
{
TT_BDF bdf = &face->bdf;
if ( bdf->loaded )
{
FT_Stream stream = FT_FACE(face)->stream;
if ( bdf->table != NULL )
FT_FRAME_RELEASE( bdf->table );
bdf->table_end = NULL;
bdf->strings = NULL;
bdf->strings_size = 0;
}
}
static FT_Error
tt_face_load_bdf_props( TT_Face face,
FT_Stream stream )
{
TT_BDF bdf = &face->bdf;
FT_ULong length;
FT_Error error;
FT_ZERO( bdf );
error = tt_face_goto_table( face, TTAG_BDF, stream, &length );
if ( error ||
length < 8 ||
FT_FRAME_EXTRACT( length, bdf->table ) )
{
error = FT_Err_Invalid_Table;
goto Exit;
}
bdf->table_end = bdf->table + length;
{
FT_Byte* p = bdf->table;
FT_UInt version = FT_NEXT_USHORT(p);
FT_UInt num_strikes = FT_NEXT_USHORT(p);
FT_UInt32 strings = FT_NEXT_ULONG(p);
if ( version != 0x0001 ||
strings < 8 ||
(strings-8)/4 < num_strikes ||
strings+1 > length )
{
BadTable:
FT_FRAME_RELEASE( bdf->table );
FT_ZERO( bdf );
error = FT_Err_Invalid_Table;
goto Exit;
}
bdf->num_strikes = num_strikes;
bdf->strings = bdf->table + strings;
bdf->strings_size = length - strings;
}
/* check the strike descriptors
*/
{
FT_UInt count = bdf->num_strikes;
FT_Byte* p = bdf->table + 8;
FT_Byte* strike = p + count*4;
for ( ; count > 0; count-- )
{
FT_UInt num_items = FT_PEEK_USHORT(p+2);
/* we don't need to check the value sets themselves, since this
* is done later
*/
strike += 10*num_items;
p += 4;
}
if ( strike > bdf->strings )
goto BadTable;
}
bdf->loaded = 1;
Exit:
return error;
}
FT_LOCAL_DEF( FT_Error )
tt_face_find_bdf_prop( TT_Face face,
const char* property_name,
BDF_PropertyRec *aprop )
{
TT_BDF bdf = &face->bdf;
FT_Size size = FT_FACE(face)->size;
FT_Error error = 0;
FT_Byte* p;
FT_UInt count;
FT_Byte* strike;
FT_UInt property_len;
aprop->type = BDF_PROPERTY_TYPE_NONE;
if ( bdf->loaded == 0 )
{
error = tt_face_load_bdf_props( face, FT_FACE(face)->stream );
if ( error )
goto Exit;
}
count = bdf->num_strikes;
p = bdf->table + 8;
strike = p + 4*count;
error = FT_Err_Invalid_Argument;
if ( size == NULL || property_name == NULL )
goto Exit;
property_len = ft_strlen( property_name );
if ( property_len == 0 )
goto Exit;
for ( ; count > 0; count-- )
{
FT_UInt _ppem = FT_NEXT_USHORT(p);
FT_UInt _count = FT_NEXT_USHORT(p);
if ( _ppem == size->metrics.y_ppem )
{
count = _count;
goto FoundStrike;
}
strike += 10*_count;
}
goto Exit;
FoundStrike:
p = strike;
for ( ; count > 0; count-- )
{
FT_UInt type = FT_PEEK_USHORT(p+4);
if ( (type & 0x10) != 0 )
{
FT_UInt32 name_offset = FT_PEEK_ULONG(p);
FT_UInt32 value = FT_PEEK_ULONG(p+6);
/* be a bit paranoid for invalid entries here */
if ( name_offset < bdf->strings_size &&
property_len < bdf->strings_size - name_offset &&
ft_strncmp( property_name, (const char*)bdf->strings + name_offset,
bdf->strings_size - name_offset ) == 0 )
{
switch ( type & 0x0F )
{
case 0x00: /* string */
case 0x01: /* atoms */
/* check that the content is really 0-terminated */
if ( value < bdf->strings_size &&
ft_memchr( bdf->strings + value, 0, bdf->strings_size ) )
{
aprop->type = BDF_PROPERTY_TYPE_ATOM;
aprop->u.atom = (const char*) bdf->strings + value;
error = 0;
goto Exit;
}
break;
case 0x02:
aprop->type = BDF_PROPERTY_TYPE_INTEGER;
aprop->u.integer = (FT_Int32)value;
error = 0;
goto Exit;
case 0x03:
aprop->type = BDF_PROPERTY_TYPE_CARDINAL;
aprop->u.cardinal = value;
error = 0;
goto Exit;
default:
;
}
}
}
p += 10;
}
Exit:
return error;
}
#endif /* TT_CONFIG_OPTION_BDF */

46
src/sfnt/ttbdf.h Normal file
View File

@ -0,0 +1,46 @@
/***************************************************************************/
/* */
/* ttbdf.h */
/* */
/* TrueType and OpenType embedded BDF properties (specification). */
/* */
/* Copyright 2005 by */
/* David Turner, Robert Wilhelm, and Werner Lemberg. */
/* */
/* This file is part of the FreeType project, and may only be used, */
/* modified, and distributed under the terms of the FreeType project */
/* license, LICENSE.TXT. By continuing to use, modify, or distribute */
/* this file you indicate that you have read the license and */
/* understand and accept it fully. */
/* */
/***************************************************************************/
#ifndef __TTBDF_H__
#define __TTBDF_H__
#include <ft2build.h>
#include "ttload.h"
#include FT_BDF_H
FT_BEGIN_HEADER
FT_LOCAL( void )
tt_face_free_bdf_props( TT_Face face );
FT_LOCAL( FT_Error )
tt_face_find_bdf_prop( TT_Face face,
const char* property_name,
BDF_PropertyRec *aprop );
FT_END_HEADER
#endif /* __TTBDF_H__ */
/* END */