* 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:
parent
8def3c897f
commit
89a2a4b531
@ -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...
|
||||
|
@ -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
|
||||
|
||||
|
||||
/* */
|
||||
|
||||
/*
|
||||
|
@ -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
|
||||
|
@ -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 */
|
||||
|
@ -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' )
|
||||
|
@ -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
|
||||
{
|
||||
|
@ -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
|
||||
|
||||
|
@ -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", ®istry );
|
||||
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 },
|
||||
|
||||
|
@ -33,5 +33,8 @@
|
||||
#include "ttpost.c"
|
||||
#endif
|
||||
|
||||
#ifdef TT_CONFIG_OPTION_BDF
|
||||
#include "ttbdf.c"
|
||||
#endif
|
||||
|
||||
/* END */
|
||||
|
@ -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
237
src/sfnt/ttbdf.c
Normal 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
46
src/sfnt/ttbdf.h
Normal 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 */
|
Loading…
Reference in New Issue
Block a user