updated freetype to 2.3.0
git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@19960 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
parent
ca48070032
commit
76b72c03e8
@ -4,7 +4,7 @@
|
||||
/* */
|
||||
/* Build macros of the FreeType 2 library. */
|
||||
/* */
|
||||
/* Copyright 1996-2001, 2002, 2003, 2004, 2005, 2006 by */
|
||||
/* Copyright 1996-2001, 2002, 2003, 2004, 2005, 2006, 2007 by */
|
||||
/* David Turner, Robert Wilhelm, and Werner Lemberg. */
|
||||
/* */
|
||||
/* This file is part of the FreeType project, and may only be used, */
|
||||
@ -88,7 +88,7 @@
|
||||
/* limited to the infamous 8.3 naming rule required by DOS (and */
|
||||
/* `FT_MULTIPLE_MASTERS_H' is a lot more meaningful than `ftmm.h'). */
|
||||
/* */
|
||||
/* The second reason is that is allows for more flexibility in the */
|
||||
/* The second reason is that it allows for more flexibility in the */
|
||||
/* way FreeType 2 is installed on a given system. */
|
||||
/* */
|
||||
/*************************************************************************/
|
||||
@ -222,7 +222,7 @@
|
||||
* FT_IMAGE_H
|
||||
*
|
||||
* @description:
|
||||
* A macro used in #include statements to name the file containing types
|
||||
* A macro used in #include statements to name the file containing type
|
||||
* definitions related to glyph images (i.e., bitmaps, outlines,
|
||||
* scan-converter parameters).
|
||||
*
|
||||
@ -282,7 +282,7 @@
|
||||
*
|
||||
* @description:
|
||||
* A macro used in #include statements to name the file containing the
|
||||
* API used to manage multiple @FT_Size objects per face.
|
||||
* API which manages multiple @FT_Size objects per face.
|
||||
*
|
||||
*/
|
||||
#define FT_SIZES_H <freetype/ftsizes.h>
|
||||
@ -334,10 +334,9 @@
|
||||
*
|
||||
* @description:
|
||||
* A macro used in #include statements to name the file containing the
|
||||
* enumeration values used to identify name strings, languages,
|
||||
* encodings, etc. This file really contains a _large_ set of constant
|
||||
* macro definitions, taken from the TrueType and OpenType
|
||||
* specifications.
|
||||
* enumeration values which identify name strings, languages, encodings,
|
||||
* etc. This file really contains a _large_ set of constant macro
|
||||
* definitions, taken from the TrueType and OpenType specifications.
|
||||
*
|
||||
*/
|
||||
#define FT_TRUETYPE_IDS_H <freetype/ttnameid.h>
|
||||
@ -363,7 +362,7 @@
|
||||
*
|
||||
* @description:
|
||||
* A macro used in #include statements to name the file containing the
|
||||
* definitions of TrueType four-byte `tags' used to identify blocks in
|
||||
* definitions of TrueType four-byte `tags' which identify blocks in
|
||||
* SFNT-based font formats (i.e., TrueType and OpenType).
|
||||
*
|
||||
*/
|
||||
@ -377,7 +376,8 @@
|
||||
*
|
||||
* @description:
|
||||
* A macro used in #include statements to name the file containing the
|
||||
* definitions of an API to access BDF-specific strings from a face.
|
||||
* definitions of an API which accesses BDF-specific strings from a
|
||||
* face.
|
||||
*
|
||||
*/
|
||||
#define FT_BDF_H <freetype/ftbdf.h>
|
||||
@ -390,7 +390,7 @@
|
||||
*
|
||||
* @description:
|
||||
* A macro used in #include statements to name the file containing the
|
||||
* definitions of an API to support for gzip-compressed files.
|
||||
* definitions of an API which supports gzip-compressed files.
|
||||
*
|
||||
*/
|
||||
#define FT_GZIP_H <freetype/ftgzip.h>
|
||||
@ -403,7 +403,7 @@
|
||||
*
|
||||
* @description:
|
||||
* A macro used in #include statements to name the file containing the
|
||||
* definitions of an API to support for LZW-compressed files.
|
||||
* definitions of an API which supports LZW-compressed files.
|
||||
*
|
||||
*/
|
||||
#define FT_LZW_H <freetype/ftlzw.h>
|
||||
@ -416,7 +416,7 @@
|
||||
*
|
||||
* @description:
|
||||
* A macro used in #include statements to name the file containing the
|
||||
* definitions of an API to support Windows FNT files.
|
||||
* definitions of an API which supports Windows FNT files.
|
||||
*
|
||||
*/
|
||||
#define FT_WINFONTS_H <freetype/ftwinfnt.h>
|
||||
@ -484,7 +484,7 @@
|
||||
* `glyph image' API of the FreeType 2 cache sub-system.
|
||||
*
|
||||
* It is used to define a cache for @FT_Glyph elements. You can also
|
||||
* see the API defined in @FT_CACHE_SMALL_BITMAPS_H if you only need to
|
||||
* use the API defined in @FT_CACHE_SMALL_BITMAPS_H if you only need to
|
||||
* store small glyph bitmaps, as it will use less memory.
|
||||
*
|
||||
* This macro is deprecated. Simply include @FT_CACHE_H to have all
|
||||
@ -568,7 +568,7 @@
|
||||
*
|
||||
* @description:
|
||||
* A macro used in #include statements to name the file containing the
|
||||
* optional FreeType 2 API used to access embedded `name' strings in
|
||||
* optional FreeType 2 API which accesses embedded `name' strings in
|
||||
* SFNT-based font formats (i.e., TrueType and OpenType).
|
||||
*
|
||||
*/
|
||||
@ -582,7 +582,7 @@
|
||||
*
|
||||
* @description:
|
||||
* A macro used in #include statements to name the file containing the
|
||||
* optional FreeType 2 API used to validate OpenType tables (BASE, GDEF,
|
||||
* optional FreeType 2 API which validates OpenType tables (BASE, GDEF,
|
||||
* GPOS, GSUB, JSTF).
|
||||
*
|
||||
*/
|
||||
@ -596,7 +596,7 @@
|
||||
*
|
||||
* @description:
|
||||
* A macro used in #include statements to name the file containing the
|
||||
* optional FreeType 2 API used to validate TrueTypeGX/AAT tables (feat,
|
||||
* optional FreeType 2 API which validates TrueTypeGX/AAT tables (feat,
|
||||
* mort, morx, bsln, just, kern, opbd, trak, prop).
|
||||
*
|
||||
*/
|
||||
@ -610,7 +610,7 @@
|
||||
*
|
||||
* @description:
|
||||
* A macro used in #include statements to name the file containing the
|
||||
* FreeType 2 API used to access PFR-specific data.
|
||||
* FreeType 2 API which accesses PFR-specific data.
|
||||
*
|
||||
*/
|
||||
#define FT_PFR_H <freetype/ftpfr.h>
|
||||
@ -623,7 +623,7 @@
|
||||
*
|
||||
* @description:
|
||||
* A macro used in #include statements to name the file containing the
|
||||
* FreeType 2 API used to stroke outline path.
|
||||
* FreeType 2 API which provides functions to stroke outline paths.
|
||||
*/
|
||||
#define FT_STROKER_H <freetype/ftstroke.h>
|
||||
|
||||
@ -635,7 +635,7 @@
|
||||
*
|
||||
* @description:
|
||||
* A macro used in #include statements to name the file containing the
|
||||
* FreeType 2 API used to perform artificial obliquing and emboldening.
|
||||
* FreeType 2 API which performs artificial obliquing and emboldening.
|
||||
*/
|
||||
#define FT_SYNTHESIS_H <freetype/ftsynth.h>
|
||||
|
||||
@ -647,7 +647,7 @@
|
||||
*
|
||||
* @description:
|
||||
* A macro used in #include statements to name the file containing the
|
||||
* FreeType 2 API used to provide functions specific to the XFree86 and
|
||||
* FreeType 2 API which provides functions specific to the XFree86 and
|
||||
* X.Org X11 servers.
|
||||
*/
|
||||
#define FT_XFREE86_H <freetype/ftxf86.h>
|
||||
@ -660,11 +660,36 @@
|
||||
*
|
||||
* @description:
|
||||
* A macro used in #include statements to name the file containing the
|
||||
* FreeType 2 API used to perform trigonometric computations (e.g.,
|
||||
* FreeType 2 API which performs trigonometric computations (e.g.,
|
||||
* cosines and arc tangents).
|
||||
*/
|
||||
#define FT_TRIGONOMETRY_H <freetype/fttrigon.h>
|
||||
|
||||
|
||||
/*************************************************************************
|
||||
*
|
||||
* @macro:
|
||||
* FT_LCD_FILTER_H
|
||||
*
|
||||
* @description:
|
||||
* A macro used in #include statements to name the file containing the
|
||||
* FreeType 2 API which performs color filtering for subpixel rendering.
|
||||
*/
|
||||
#define FT_LCD_FILTER_H <freetype/ftlcdfil.h>
|
||||
|
||||
|
||||
/*************************************************************************
|
||||
*
|
||||
* @macro:
|
||||
* FT_GASP_H
|
||||
*
|
||||
* @description:
|
||||
* A macro used in #include statements to name the file containing the
|
||||
* FreeType 2 API which returns entries from the TrueType GASP table.
|
||||
*/
|
||||
#define FT_GASP_H <freetype/ftgasp.h>
|
||||
|
||||
|
||||
/* */
|
||||
|
||||
#define FT_ERROR_DEFINITIONS_H <freetype/fterrdef.h>
|
||||
|
@ -4,7 +4,7 @@
|
||||
/* */
|
||||
/* User-selectable configuration macros (specification only). */
|
||||
/* */
|
||||
/* Copyright 1996-2001, 2002, 2003, 2004, 2005, 2006 by */
|
||||
/* Copyright 1996-2001, 2002, 2003, 2004, 2005, 2006, 2007 by */
|
||||
/* David Turner, Robert Wilhelm, and Werner Lemberg. */
|
||||
/* */
|
||||
/* This file is part of the FreeType project, and may only be used, */
|
||||
@ -75,6 +75,26 @@ FT_BEGIN_HEADER
|
||||
/*************************************************************************/
|
||||
|
||||
|
||||
/*************************************************************************/
|
||||
/* */
|
||||
/* Uncomment the line below if you want to activate sub-pixel rendering */
|
||||
/* (a.k.a. LCD rendering, or ClearType) in this build of the library. */
|
||||
/* */
|
||||
/* Note that this feature is covered by several Microsoft patents */
|
||||
/* and should not be activated in any default build of the library. */
|
||||
/* */
|
||||
/* This macro has no impact on the FreeType API, only on its */
|
||||
/* _implementation_. For example, using FT_RENDER_MODE_LCD when calling */
|
||||
/* FT_Render_Glyph still generates a bitmap that is 3 times larger than */
|
||||
/* the original size; the difference will be that each triplet of */
|
||||
/* subpixels has R=G=B. */
|
||||
/* */
|
||||
/* This is done to allow FreeType clients to run unmodified, forcing */
|
||||
/* them to display normal gray-level anti-aliased glyphs. */
|
||||
/* */
|
||||
#define FT_CONFIG_OPTION_SUBPIXEL_RENDERING
|
||||
|
||||
|
||||
/*************************************************************************/
|
||||
/* */
|
||||
/* Many compilers provide a non-ANSI 64-bit data type that can be used */
|
||||
@ -448,7 +468,7 @@ FT_BEGIN_HEADER
|
||||
/* FT_PARAM_TAG_UNPATENTED_HINTING; or when the debug hook */
|
||||
/* FT_DEBUG_HOOK_UNPATENTED_HINTING is globally activated. */
|
||||
/* */
|
||||
//#define TT_CONFIG_OPTION_UNPATENTED_HINTING
|
||||
#define TT_CONFIG_OPTION_UNPATENTED_HINTING
|
||||
|
||||
|
||||
/*************************************************************************/
|
||||
@ -572,13 +592,7 @@ FT_BEGIN_HEADER
|
||||
#define AF_CONFIG_OPTION_CJK
|
||||
|
||||
|
||||
/* */
|
||||
|
||||
/*
|
||||
* This temporary macro is used to control various optimizations for
|
||||
* reducing the heap footprint of memory-mapped TrueType files.
|
||||
*/
|
||||
#define FT_OPTIMIZE_MEMORY
|
||||
/* */
|
||||
|
||||
|
||||
/*
|
||||
@ -594,6 +608,16 @@ FT_BEGIN_HEADER
|
||||
#define FT_CONFIG_OPTION_OLD_INTERNALS
|
||||
|
||||
|
||||
/*
|
||||
* This variable is defined if either unpatented or native TrueType
|
||||
* hinting is requested by the definitions above.
|
||||
*/
|
||||
#ifdef TT_CONFIG_OPTION_BYTECODE_INTERPRETER
|
||||
#define TT_USE_BYTECODE_INTERPRETER
|
||||
#elif defined TT_CONFIG_OPTION_UNPATENTED_HINTING
|
||||
#define TT_USE_BYTECODE_INTERPRETER
|
||||
#endif
|
||||
|
||||
FT_END_HEADER
|
||||
|
||||
|
||||
|
@ -168,12 +168,12 @@
|
||||
|
||||
#include <setjmp.h>
|
||||
|
||||
#define ft_jmp_buf jmp_buf /* note: this cannot be a typedef since */
|
||||
/* jmp_buf is defined as a macro */
|
||||
/* on certain platforms */
|
||||
#define ft_jmp_buf jmp_buf /* note: this cannot be a typedef since */
|
||||
/* jmp_buf is defined as a macro */
|
||||
/* on certain platforms */
|
||||
|
||||
#define ft_longjmp longjmp /* likewise */
|
||||
#define ft_setjmp setjmp /* same thing here */
|
||||
#define ft_longjmp longjmp
|
||||
#define ft_setjmp( b ) setjmp( *(jmp_buf*) &(b) ) /* same thing here */
|
||||
|
||||
|
||||
/* the following is only used for debugging purposes, i.e., if */
|
||||
|
@ -4,7 +4,7 @@
|
||||
/* */
|
||||
/* FreeType high-level API and common types (specification only). */
|
||||
/* */
|
||||
/* Copyright 1996-2001, 2002, 2003, 2004, 2005, 2006 by */
|
||||
/* Copyright 1996-2001, 2002, 2003, 2004, 2005, 2006, 2007 by */
|
||||
/* David Turner, Robert Wilhelm, and Werner Lemberg. */
|
||||
/* */
|
||||
/* This file is part of the FreeType project, and may only be used, */
|
||||
@ -913,7 +913,9 @@ FT_BEGIN_HEADER
|
||||
|
||||
FT_Generic generic;
|
||||
|
||||
/*# the following are only relevant to scalable outlines */
|
||||
/*# The following member variables (down to `underline_thickness') */
|
||||
/*# are only relevant to scalable outlines; cf. @FT_Bitmap_Size */
|
||||
/*# for bitmap fonts. */
|
||||
FT_BBox bbox;
|
||||
|
||||
FT_UShort units_per_EM;
|
||||
@ -1270,6 +1272,8 @@ FT_BEGIN_HEADER
|
||||
/* glyphs. As this would be a definite performance hit, it is up to */
|
||||
/* client applications to perform such computations. */
|
||||
/* */
|
||||
/* The FT_Size_Metrics structure is valid for bitmap fonts also. */
|
||||
/* */
|
||||
typedef struct FT_Size_Metrics_
|
||||
{
|
||||
FT_UShort x_ppem; /* horizontal pixels per EM */
|
||||
@ -1795,6 +1799,9 @@ FT_BEGIN_HEADER
|
||||
/* <Return> */
|
||||
/* FreeType error code. 0 means success. */
|
||||
/* */
|
||||
/* <Note> */
|
||||
/* You must not deallocate the memory before calling @FT_Done_Face. */
|
||||
/* */
|
||||
FT_EXPORT( FT_Error )
|
||||
FT_New_Memory_Face( FT_Library library,
|
||||
const FT_Byte* file_base,
|
||||
@ -3306,8 +3313,8 @@ FT_BEGIN_HEADER
|
||||
* macros.
|
||||
*/
|
||||
#define FREETYPE_MAJOR 2
|
||||
#define FREETYPE_MINOR 2
|
||||
#define FREETYPE_PATCH 1
|
||||
#define FREETYPE_MINOR 3
|
||||
#define FREETYPE_PATCH 0
|
||||
|
||||
|
||||
/*************************************************************************/
|
||||
@ -3345,7 +3352,6 @@ FT_BEGIN_HEADER
|
||||
FT_Int *aminor,
|
||||
FT_Int *apatch );
|
||||
|
||||
|
||||
/* */
|
||||
|
||||
|
||||
|
@ -3,7 +3,7 @@
|
||||
/* ftbitmap.h */
|
||||
/* */
|
||||
/* FreeType utility functions for converting 1bpp, 2bpp, 4bpp, and 8bpp */
|
||||
/* bitmaps into 8bpp format (specification). */
|
||||
/* bitmaps into 8bpp format (specification). */
|
||||
/* */
|
||||
/* Copyright 2004, 2005, 2006 by */
|
||||
/* David Turner, Robert Wilhelm, and Werner Lemberg. */
|
||||
|
@ -56,6 +56,8 @@
|
||||
/* bdf_fonts */
|
||||
/* pfr_fonts */
|
||||
/* winfnt_fonts */
|
||||
/* font_formats */
|
||||
/* gasp_table */
|
||||
/* */
|
||||
/***************************************************************************/
|
||||
|
||||
@ -93,5 +95,6 @@
|
||||
/* module_management */
|
||||
/* gzip */
|
||||
/* lzw */
|
||||
/* lcd_filtering */
|
||||
/* */
|
||||
/***************************************************************************/
|
||||
|
113
headers/libs/freetype2/freetype/ftgasp.h
Normal file
113
headers/libs/freetype2/freetype/ftgasp.h
Normal file
@ -0,0 +1,113 @@
|
||||
/***************************************************************************/
|
||||
/* */
|
||||
/* ftgasp.h */
|
||||
/* */
|
||||
/* Access of TrueType's `gasp' table (specification). */
|
||||
/* */
|
||||
/* Copyright 2007 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 _FT_GASP_H_
|
||||
#define _FT_GASP_H_
|
||||
|
||||
#include <ft2build.h>
|
||||
#include FT_FREETYPE_H
|
||||
|
||||
/***************************************************************************
|
||||
*
|
||||
* @section:
|
||||
* gasp_table
|
||||
*
|
||||
* @title:
|
||||
* Gasp Table
|
||||
*
|
||||
* @abstract:
|
||||
* Retrieving TrueType `gasp' table entries
|
||||
*
|
||||
* @description:
|
||||
* The function @FT_Get_Gasp can be used to query a TrueType or OpenType
|
||||
* font for specific entries in their `gasp' table, if any. This is
|
||||
* mainly useful when implementing native TrueType hinting with the
|
||||
* bytecode interpreter to duplicate the Windows text rendering results.
|
||||
*/
|
||||
|
||||
/*************************************************************************
|
||||
*
|
||||
* @enum:
|
||||
* FT_GASP_XXX
|
||||
*
|
||||
* @description:
|
||||
* A list of values and/or bit-flags returned by the @FT_Get_Gasp
|
||||
* function.
|
||||
*
|
||||
* @values:
|
||||
* FT_GASP_NO_TABLE ::
|
||||
* This special value means that there is no GASP table in this face.
|
||||
* It is up to the client to decide what to do.
|
||||
*
|
||||
* FT_GASP_DO_GRIDFIT ::
|
||||
* Grid-fitting and hinting should be performed at the specified ppem.
|
||||
* This *really* means TrueType bytecode interpretation.
|
||||
*
|
||||
* FT_GASP_DO_GRAY ::
|
||||
* Anti-aliased rendering should be performed at the specified ppem.
|
||||
*
|
||||
* FT_GASP_SYMMETRIC_SMOOTHING ::
|
||||
* Smoothing along multiple axes must be used with ClearType.
|
||||
*
|
||||
* FT_GASP_SYMMETRIC_GRIDFIT ::
|
||||
* Grid-fitting must be used with ClearType's symmetric smoothing.
|
||||
*
|
||||
* @note:
|
||||
* `ClearType' is Microsoft's implementation of LCD rendering, partly
|
||||
* protected by patents.
|
||||
*
|
||||
* @since:
|
||||
* 2.3.0
|
||||
*/
|
||||
#define FT_GASP_NO_TABLE -1
|
||||
#define FT_GASP_DO_GRIDFIT 0x01
|
||||
#define FT_GASP_DO_GRAY 0x02
|
||||
#define FT_GASP_SYMMETRIC_SMOOTHING 0x08
|
||||
#define FT_GASP_SYMMETRIC_GRIDFIT 0x10
|
||||
|
||||
|
||||
/*************************************************************************
|
||||
*
|
||||
* @func:
|
||||
* FT_Get_Gasp
|
||||
*
|
||||
* @description:
|
||||
* Read the `gasp' table from a TrueType or OpenType font file and
|
||||
* return the entry corresponding to a given character pixel size.
|
||||
*
|
||||
* @input:
|
||||
* face :: The source face handle.
|
||||
* ppem :: The vertical character pixel size.
|
||||
*
|
||||
* @return:
|
||||
* Bit flags (see @FT_GASP_XXX), or @FT_GASP_NO_TABLE is there is no
|
||||
* `gasp' table in the face.
|
||||
*
|
||||
* @since:
|
||||
* 2.3.0
|
||||
*/
|
||||
FT_EXPORT( FT_Int )
|
||||
FT_Get_Gasp( FT_Face face,
|
||||
FT_UInt ppem );
|
||||
|
||||
/* */
|
||||
|
||||
#endif /* _FT_GASP_H_ */
|
||||
|
||||
|
||||
/* END */
|
@ -229,11 +229,11 @@ FT_BEGIN_HEADER
|
||||
*
|
||||
* @struct:
|
||||
* FT_Incremental_FuncsRec
|
||||
*
|
||||
*
|
||||
* @description:
|
||||
* A table of functions for accessing fonts that load data
|
||||
* incrementally. Used in @FT_Incremental_InterfaceRec.
|
||||
*
|
||||
*
|
||||
* @fields:
|
||||
* get_glyph_data ::
|
||||
* The function to get glyph data. Must not be null.
|
||||
@ -243,7 +243,7 @@ FT_BEGIN_HEADER
|
||||
*
|
||||
* get_glyph_metrics ::
|
||||
* The function to get glyph metrics. May be null if the font does
|
||||
* not provide overriding glyph metrics.
|
||||
* not provide overriding glyph metrics.
|
||||
*/
|
||||
typedef struct FT_Incremental_FuncsRec_
|
||||
{
|
||||
@ -293,7 +293,7 @@ FT_BEGIN_HEADER
|
||||
{
|
||||
const FT_Incremental_FuncsRec* funcs;
|
||||
FT_Incremental object;
|
||||
|
||||
|
||||
} FT_Incremental_InterfaceRec;
|
||||
|
||||
|
||||
@ -321,7 +321,7 @@ FT_BEGIN_HEADER
|
||||
*/
|
||||
#define FT_PARAM_TAG_INCREMENTAL FT_MAKE_TAG( 'i', 'n', 'c', 'r' )
|
||||
|
||||
/* */
|
||||
/* */
|
||||
|
||||
FT_END_HEADER
|
||||
|
||||
|
166
headers/libs/freetype2/freetype/ftlcdfil.h
Normal file
166
headers/libs/freetype2/freetype/ftlcdfil.h
Normal file
@ -0,0 +1,166 @@
|
||||
/***************************************************************************/
|
||||
/* */
|
||||
/* ftlcdfil.h */
|
||||
/* */
|
||||
/* FreeType API for color filtering of subpixel bitmap glyphs */
|
||||
/* (specification). */
|
||||
/* */
|
||||
/* Copyright 2006, 2007 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 __FT_LCD_FILTER_H__
|
||||
#define __FT_LCD_FILTER_H__
|
||||
|
||||
#include <ft2build.h>
|
||||
#include FT_FREETYPE_H
|
||||
|
||||
|
||||
FT_BEGIN_HEADER
|
||||
|
||||
/***************************************************************************
|
||||
*
|
||||
* @section:
|
||||
* lcd_filtering
|
||||
*
|
||||
* @title:
|
||||
* LCD Filtering
|
||||
*
|
||||
* @abstract:
|
||||
* Reduce color fringes of LCD-optimized bitmaps.
|
||||
*
|
||||
* @description:
|
||||
* The @FT_Library_SetLcdFilter API can be used to specify a low-pass
|
||||
* filter which is then applied to LCD-optimized bitmaps generated
|
||||
* through @FT_Render_Glyph. This is useful to reduce color fringes
|
||||
* which would occur with unfiltered rendering.
|
||||
*
|
||||
* Note that no filter is active by default, and that this function is
|
||||
* *not* implemented in default builds of the library. You need to
|
||||
* #define FT_CONFIG_OPTION_SUBPIXEL_RENDERING in your `ftoption.h' file
|
||||
* in order to activate it.
|
||||
*/
|
||||
|
||||
|
||||
/****************************************************************************
|
||||
*
|
||||
* @func:
|
||||
* FT_LcdFilter
|
||||
*
|
||||
* @description:
|
||||
* A list of values to identify various types of LCD filters.
|
||||
*
|
||||
* @values:
|
||||
* FT_LCD_FILTER_NONE ::
|
||||
* Do not perform filtering. When used with subpixel rendering, this
|
||||
* results in sometimes severe color fringes.
|
||||
*
|
||||
* FT_LCD_FILTER_DEFAULT ::
|
||||
* The default filter reduces color fringes considerably, at the cost
|
||||
* of a slight blurriness in the output.
|
||||
*
|
||||
* FT_LCD_FILTER_LIGHT ::
|
||||
* The light filter is a variant that produces less blurriness at the
|
||||
* cost of slightly more color fringes than the default one. It might
|
||||
* be better, depending on taste, your monitor, or your personal vision.
|
||||
*
|
||||
* FT_LCD_FILTER_LEGACY ::
|
||||
* This filter corresponds to the original libXft color filter. It
|
||||
* provides high contrast output but can exhibit really bad color
|
||||
* fringes if glyphs are not extremely well hinted to the pixel grid.
|
||||
* In other words, it only works well if the TrueType bytecode
|
||||
* interpreter is enabled *and* high-quality hinted fonts are used.
|
||||
*
|
||||
* This filter is only provided for comparison purposes, and might be
|
||||
* disabled or stay unsupported in the future.
|
||||
*
|
||||
* @since:
|
||||
* 2.3.0
|
||||
*/
|
||||
typedef enum
|
||||
{
|
||||
FT_LCD_FILTER_NONE = 0,
|
||||
FT_LCD_FILTER_DEFAULT = 1,
|
||||
FT_LCD_FILTER_LIGHT = 2,
|
||||
FT_LCD_FILTER_LEGACY = 16,
|
||||
|
||||
FT_LCD_FILTER_MAX /* do not remove */
|
||||
|
||||
} FT_LcdFilter;
|
||||
|
||||
|
||||
/**************************************************************************
|
||||
*
|
||||
* @func:
|
||||
* FT_Library_SetLcdFilter
|
||||
*
|
||||
* @description:
|
||||
* This function is used to apply color filtering to LCD decimated
|
||||
* bitmaps, like the ones used when calling @FT_Render_Glyph with
|
||||
* @FT_RENDER_MODE_LCD or @FT_RENDER_MODE_LCD_V.
|
||||
*
|
||||
* @input:
|
||||
* library ::
|
||||
* A handle to the target library instance.
|
||||
*
|
||||
* filter ::
|
||||
* The filter type.
|
||||
*
|
||||
* You can use @FT_LCD_FILTER_NONE here to disable this feature, or
|
||||
* @FT_LCD_FILTER_DEFAULT to use a default filter that should work
|
||||
* well on most LCD screens.
|
||||
*
|
||||
* @return:
|
||||
* FreeType error code. 0 means success.
|
||||
*
|
||||
* @note:
|
||||
* This feature is always disabled by default. Clients must make an
|
||||
* explicit call to this function with a `filter' value other than
|
||||
* @FT_LCD_FILTER_NONE in order to enable it.
|
||||
*
|
||||
* Due to *PATENTS* covering subpixel rendering, this function doesn't
|
||||
* do anything except returning `FT_Err_Unimplemented_Feature' if the
|
||||
* configuration macro FT_CONFIG_OPTION_SUBPIXEL_RENDERING is not
|
||||
* defined in your build of the library, which should correspond to all
|
||||
* default builds of FreeType.
|
||||
*
|
||||
* The filter affects glyph bitmaps rendered through @FT_Render_Glyph,
|
||||
* @FT_Outline_Get_Bitmap, @FT_Load_Glyph, and @FT_Load_Char.
|
||||
*
|
||||
* It does _not_ affect the output of @FT_Outline_Render and
|
||||
* @FT_Outline_Get_Bitmap.
|
||||
*
|
||||
* If this feature is activated, the dimensions of LCD glyph bitmaps are
|
||||
* either larger or taller than the dimensions of the corresponding
|
||||
* outline with regards to the pixel grid. For example, for
|
||||
* @FT_RENDER_MODE_LCD, the filter adds up to 3 pixels to the left, and
|
||||
* up to 3 pixels to the right.
|
||||
*
|
||||
* The bitmap offset values are adjusted correctly, so clients shouldn't
|
||||
* need to modify their layout and glyph positioning code when enabling
|
||||
* the filter.
|
||||
*
|
||||
* @since:
|
||||
* 2.3.0
|
||||
*/
|
||||
FT_EXPORT( FT_Error )
|
||||
FT_Library_SetLcdFilter( FT_Library library,
|
||||
FT_LcdFilter filter );
|
||||
|
||||
/* */
|
||||
|
||||
|
||||
FT_END_HEADER
|
||||
|
||||
#endif /* __FT_LCD_FILTER_H__ */
|
||||
|
||||
|
||||
/* END */
|
@ -154,10 +154,10 @@ FT_BEGIN_HEADER
|
||||
FT_EXPORT( FT_Error )
|
||||
FT_OpenType_Validate( FT_Face face,
|
||||
FT_UInt validation_flags,
|
||||
FT_Bytes *BASE_table,
|
||||
FT_Bytes *GDEF_table,
|
||||
FT_Bytes *GPOS_table,
|
||||
FT_Bytes *GSUB_table,
|
||||
FT_Bytes *BASE_table,
|
||||
FT_Bytes *GDEF_table,
|
||||
FT_Bytes *GPOS_table,
|
||||
FT_Bytes *GSUB_table,
|
||||
FT_Bytes *JSTF_table );
|
||||
|
||||
/* */
|
||||
|
@ -442,13 +442,13 @@ FT_BEGIN_HEADER
|
||||
*
|
||||
* @enum:
|
||||
* FT_Orientation
|
||||
*
|
||||
*
|
||||
* @description:
|
||||
* A list of values used to describe an outline's contour orientation.
|
||||
*
|
||||
* The TrueType and Postscript specifications use different conventions
|
||||
* to determine whether outline contours should be filled or unfilled.
|
||||
*
|
||||
*
|
||||
* @values:
|
||||
* FT_ORIENTATION_TRUETYPE ::
|
||||
* According to the TrueType specification, clockwise contours must
|
||||
@ -480,7 +480,7 @@ FT_BEGIN_HEADER
|
||||
FT_ORIENTATION_FILL_RIGHT = FT_ORIENTATION_TRUETYPE,
|
||||
FT_ORIENTATION_FILL_LEFT = FT_ORIENTATION_POSTSCRIPT,
|
||||
FT_ORIENTATION_NONE
|
||||
|
||||
|
||||
} FT_Orientation;
|
||||
|
||||
|
||||
@ -488,7 +488,7 @@ FT_BEGIN_HEADER
|
||||
*
|
||||
* @function:
|
||||
* FT_Outline_Get_Orientation
|
||||
*
|
||||
*
|
||||
* @description:
|
||||
* This function analyzes a glyph outline and tries to compute its
|
||||
* fill orientation (see @FT_Orientation). This is done by computing
|
||||
|
@ -64,7 +64,7 @@ FT_BEGIN_HEADER
|
||||
*
|
||||
* @values:
|
||||
* FT_WinFNT_ID_DEFAULT ::
|
||||
* This is used for font enumeration and font creation as a
|
||||
* This is used for font enumeration and font creation as a
|
||||
* `don't care' value. Valid font files don't contain this value.
|
||||
* When querying for information about the character set of the font
|
||||
* that is currently selected into a specified device context, this
|
||||
@ -95,7 +95,7 @@ FT_BEGIN_HEADER
|
||||
* Windows have. It is one of the OEM codepages from
|
||||
*
|
||||
* http://www.microsoft.com/globaldev/reference/cphome.mspx,
|
||||
*
|
||||
*
|
||||
* and is used for the `DOS boxes', to support legacy applications.
|
||||
* A German Windows version for example usually uses ANSI codepage
|
||||
* 1252 and OEM codepage 850.
|
||||
@ -130,10 +130,10 @@ FT_BEGIN_HEADER
|
||||
*
|
||||
* FT_WinFNT_ID_CP1253 ::
|
||||
* A superset of Greek ISO 8859-7 (with minor modifications).
|
||||
*
|
||||
*
|
||||
* FT_WinFNT_ID_CP1254 ::
|
||||
* A superset of Turkish ISO 8859-9.
|
||||
*
|
||||
*
|
||||
* FT_WinFNT_ID_CP1255 ::
|
||||
* A superset of Hebrew ISO 8859-8 (with some modifications).
|
||||
*
|
||||
|
@ -4,7 +4,7 @@
|
||||
/* */
|
||||
/* Support functions for X11. */
|
||||
/* */
|
||||
/* Copyright 2002, 2003, 2004 by */
|
||||
/* Copyright 2002, 2003, 2004, 2006 by */
|
||||
/* David Turner, Robert Wilhelm, and Werner Lemberg. */
|
||||
/* */
|
||||
/* This file is part of the FreeType project, and may only be used, */
|
||||
@ -31,24 +31,44 @@
|
||||
|
||||
FT_BEGIN_HEADER
|
||||
|
||||
/* this comment is intentionally disabled for now, to prevent this */
|
||||
/* function from appearing in the API Reference. */
|
||||
|
||||
/*@***********************************************************************/
|
||||
/*************************************************************************/
|
||||
/* */
|
||||
/* <Function> */
|
||||
/* FT_Get_X11_Font_Format */
|
||||
/* <Section> */
|
||||
/* font_formats */
|
||||
/* */
|
||||
/* <Title> */
|
||||
/* Font Formats */
|
||||
/* */
|
||||
/* <Abstract> */
|
||||
/* Getting the font format. */
|
||||
/* */
|
||||
/* <Description> */
|
||||
/* Return a string describing the format of a given face as an X11 */
|
||||
/* FONT_PROPERTY. It should only be used by the FreeType 2 font */
|
||||
/* backend of the XFree86 font server. */
|
||||
/* The single function in this section can be used to get the font */
|
||||
/* format. Note that this information is not needed normally; */
|
||||
/* however, there are special cases (like in PDF devices) where it is */
|
||||
/* important to differentiate, inspite of FreeType's uniform API. */
|
||||
/* */
|
||||
/*************************************************************************/
|
||||
|
||||
|
||||
/*************************************************************************/
|
||||
/* */
|
||||
/* <Function> */
|
||||
/* FT_Get_X11_Font_Format */
|
||||
/* */
|
||||
/* <Description> */
|
||||
/* Return a string describing the format of a given face, using values */
|
||||
/* which can be used as an X11 FONT_PROPERTY. Possible values are */
|
||||
/* `TrueType', `Type 1', `BDF', `PCF', `Type 42', `CID Type 1', `CFF', */
|
||||
/* `PFR', and `Windows FNT'. */
|
||||
/* */
|
||||
/* <Input> */
|
||||
/* face :: Input face handle. */
|
||||
/* face :: */
|
||||
/* Input face handle. */
|
||||
/* */
|
||||
/* <Return> */
|
||||
/* Font format string. NULL in case of error. */
|
||||
/* Font format string. NULL in case of error. */
|
||||
/* */
|
||||
FT_EXPORT( const char* )
|
||||
FT_Get_X11_Font_Format( FT_Face face );
|
||||
|
@ -78,7 +78,7 @@ FT_BEGIN_HEADER
|
||||
/*************************************************************************/
|
||||
|
||||
|
||||
#ifdef TT_CONFIG_OPTION_BYTECODE_INTERPRETER
|
||||
#ifdef TT_USE_BYTECODE_INTERPRETER
|
||||
|
||||
/*************************************************************************/
|
||||
/* */
|
||||
@ -108,7 +108,31 @@ FT_BEGIN_HEADER
|
||||
FT_Long b,
|
||||
FT_Long c );
|
||||
|
||||
#endif /* TT_CONFIG_OPTION_BYTECODE_INTERPRETER */
|
||||
#endif /* TT_USE_BYTECODE_INTERPRETER */
|
||||
|
||||
|
||||
/*
|
||||
* Return -1, 0, or +1, depending on the orientation of a given corner.
|
||||
* We use the Cartesian coordinate system, with positive vertical values
|
||||
* going upwards. The function returns +1 if the corner turns to the
|
||||
* left, -1 to the right, and 0 for undecidable cases.
|
||||
*/
|
||||
FT_BASE( FT_Int )
|
||||
ft_corner_orientation( FT_Pos in_x,
|
||||
FT_Pos in_y,
|
||||
FT_Pos out_x,
|
||||
FT_Pos out_y );
|
||||
|
||||
/*
|
||||
* Return TRUE if a corner is flat or nearly flat. This is equivalent to
|
||||
* saying that the angle difference between the `in' and `out' vectors is
|
||||
* very small.
|
||||
*/
|
||||
FT_BASE( FT_Int )
|
||||
ft_corner_is_flat( FT_Pos in_x,
|
||||
FT_Pos in_y,
|
||||
FT_Pos out_x,
|
||||
FT_Pos out_y );
|
||||
|
||||
|
||||
#define INT_TO_F26DOT6( x ) ( (FT_Long)(x) << 6 )
|
||||
|
@ -69,6 +69,7 @@ FT_BEGIN_HEADER
|
||||
{
|
||||
FT_Outline outline; /* outline */
|
||||
FT_Vector* extra_points; /* extra points table */
|
||||
FT_Vector* extra_points2; /* second extra points table */
|
||||
FT_UInt num_subglyphs; /* number of subglyphs */
|
||||
FT_SubGlyph subglyphs; /* subglyphs */
|
||||
|
||||
|
@ -29,6 +29,7 @@
|
||||
#include <ft2build.h>
|
||||
#include FT_RENDER_H
|
||||
#include FT_SIZES_H
|
||||
#include FT_LCD_FILTER_H
|
||||
#include FT_INTERNAL_MEMORY_H
|
||||
#include FT_INTERNAL_GLYPH_LOADER_H
|
||||
#include FT_INTERNAL_DRIVER_H
|
||||
@ -211,6 +212,12 @@ FT_BEGIN_HEADER
|
||||
/* this data when first opened. This field exists only if */
|
||||
/* @FT_CONFIG_OPTION_INCREMENTAL is defined. */
|
||||
/* */
|
||||
/* ignore_unpatented_hinter :: */
|
||||
/* This boolean flag instructs the glyph loader to ignore the */
|
||||
/* native font hinter, if one is found. This is exclusively used */
|
||||
/* in the case when the unpatented hinter is compiled within the */
|
||||
/* library. */
|
||||
/* */
|
||||
typedef struct FT_Face_InternalRec_
|
||||
{
|
||||
#ifdef FT_CONFIG_OPTION_OLD_INTERNALS
|
||||
@ -227,6 +234,8 @@ FT_BEGIN_HEADER
|
||||
FT_Incremental_InterfaceRec* incremental_interface;
|
||||
#endif
|
||||
|
||||
FT_Bool ignore_unpatented_hinter;
|
||||
|
||||
} FT_Face_InternalRec;
|
||||
|
||||
|
||||
@ -621,12 +630,17 @@ FT_BEGIN_HEADER
|
||||
|
||||
|
||||
/* Set this debug hook to a non-null pointer to force unpatented hinting */
|
||||
/* for all faces when both TT_CONFIG_OPTION_BYTECODE_INTERPRETER and */
|
||||
/* TT_CONFIG_OPTION_UNPATENTED_HINTING are defined. this is only used */
|
||||
/* for all faces when both TT_USE_BYTECODE_INTERPRETER and */
|
||||
/* TT_CONFIG_OPTION_UNPATENTED_HINTING are defined. This is only used */
|
||||
/* during debugging. */
|
||||
#define FT_DEBUG_HOOK_UNPATENTED_HINTING 1
|
||||
|
||||
|
||||
typedef void (*FT_Bitmap_LcdFilterFunc)( FT_Bitmap* bitmap,
|
||||
FT_Render_Mode render_mode,
|
||||
FT_Library library );
|
||||
|
||||
|
||||
/*************************************************************************/
|
||||
/* */
|
||||
/* <Struct> */
|
||||
@ -700,6 +714,13 @@ FT_BEGIN_HEADER
|
||||
|
||||
FT_DebugHook_Func debug_hooks[4];
|
||||
|
||||
#ifdef FT_CONFIG_OPTION_SUBPIXEL_RENDERING
|
||||
FT_LcdFilter lcd_filter;
|
||||
FT_Int lcd_extra; /* number of extra pixels */
|
||||
FT_Byte lcd_weights[7]; /* filter weights, if any */
|
||||
FT_Bitmap_LcdFilterFunc lcd_filter_func; /* filtering callback */
|
||||
#endif
|
||||
|
||||
} FT_LibraryRec;
|
||||
|
||||
|
||||
|
@ -414,7 +414,7 @@ FT_BEGIN_HEADER
|
||||
/* */
|
||||
/* Useful to optimize access to memory-based streams transparently. */
|
||||
/* */
|
||||
/* All extracted frames must be `freed` with a call to the function */
|
||||
/* All extracted frames must be `freed' with a call to the function */
|
||||
/* FT_Stream_ReleaseFrame(). */
|
||||
/* */
|
||||
FT_BASE( FT_Error )
|
||||
|
@ -39,7 +39,7 @@ FT_BEGIN_HEADER
|
||||
/*************************************************************************/
|
||||
|
||||
/* handle to a validation object */
|
||||
typedef struct FT_ValidatorRec_* FT_Validator;
|
||||
typedef struct FT_ValidatorRec_ volatile* FT_Validator;
|
||||
|
||||
|
||||
/*************************************************************************/
|
||||
@ -98,6 +98,8 @@ FT_BEGIN_HEADER
|
||||
const FT_Byte* limit,
|
||||
FT_ValidationLevel level );
|
||||
|
||||
/* Do not use this. It's broken and will cause your validator to crash */
|
||||
/* if you run it on an invalid font. */
|
||||
FT_BASE( FT_Int )
|
||||
ft_validator_run( FT_Validator valid );
|
||||
|
||||
|
@ -154,6 +154,7 @@ FT_BEGIN_HEADER
|
||||
T1_TOKEN_TYPE_ANY,
|
||||
T1_TOKEN_TYPE_STRING,
|
||||
T1_TOKEN_TYPE_ARRAY,
|
||||
T1_TOKEN_TYPE_KEY, /* aka `name' */
|
||||
|
||||
/* do not remove */
|
||||
T1_TOKEN_TYPE_MAX
|
||||
@ -199,6 +200,9 @@ FT_BEGIN_HEADER
|
||||
T1_FIELD_LOCATION_FONT_INFO,
|
||||
T1_FIELD_LOCATION_PRIVATE,
|
||||
T1_FIELD_LOCATION_BBOX,
|
||||
T1_FIELD_LOCATION_LOADER,
|
||||
T1_FIELD_LOCATION_FACE,
|
||||
T1_FIELD_LOCATION_BLEND,
|
||||
|
||||
/* do not remove */
|
||||
T1_FIELD_LOCATION_MAX
|
||||
@ -224,86 +228,96 @@ FT_BEGIN_HEADER
|
||||
/* array */
|
||||
FT_UInt count_offset; /* offset of element count for */
|
||||
/* arrays */
|
||||
FT_UInt dict; /* where we expect it */
|
||||
} T1_FieldRec;
|
||||
|
||||
#define T1_FIELD_DICT_FONTDICT ( 1 << 0 ) /* also FontInfo and FDArray */
|
||||
#define T1_FIELD_DICT_PRIVATE ( 1 << 1 )
|
||||
|
||||
#define T1_NEW_SIMPLE_FIELD( _ident, _type, _fname ) \
|
||||
{ \
|
||||
_ident, T1CODE, _type, \
|
||||
0, \
|
||||
FT_FIELD_OFFSET( _fname ), \
|
||||
FT_FIELD_SIZE( _fname ), \
|
||||
0, 0 \
|
||||
|
||||
|
||||
#define T1_NEW_SIMPLE_FIELD( _ident, _type, _fname, _dict ) \
|
||||
{ \
|
||||
_ident, T1CODE, _type, \
|
||||
0, \
|
||||
FT_FIELD_OFFSET( _fname ), \
|
||||
FT_FIELD_SIZE( _fname ), \
|
||||
0, 0, \
|
||||
_dict \
|
||||
},
|
||||
|
||||
#define T1_NEW_CALLBACK_FIELD( _ident, _reader ) \
|
||||
{ \
|
||||
_ident, T1CODE, T1_FIELD_TYPE_CALLBACK, \
|
||||
(T1_Field_ParseFunc)_reader, \
|
||||
0, 0, \
|
||||
0, 0 \
|
||||
#define T1_NEW_CALLBACK_FIELD( _ident, _reader, _dict ) \
|
||||
{ \
|
||||
_ident, T1CODE, T1_FIELD_TYPE_CALLBACK, \
|
||||
(T1_Field_ParseFunc)_reader, \
|
||||
0, 0, \
|
||||
0, 0, \
|
||||
_dict \
|
||||
},
|
||||
|
||||
#define T1_NEW_TABLE_FIELD( _ident, _type, _fname, _max ) \
|
||||
{ \
|
||||
_ident, T1CODE, _type, \
|
||||
0, \
|
||||
FT_FIELD_OFFSET( _fname ), \
|
||||
FT_FIELD_SIZE_DELTA( _fname ), \
|
||||
_max, \
|
||||
FT_FIELD_OFFSET( num_ ## _fname ) \
|
||||
#define T1_NEW_TABLE_FIELD( _ident, _type, _fname, _max, _dict ) \
|
||||
{ \
|
||||
_ident, T1CODE, _type, \
|
||||
0, \
|
||||
FT_FIELD_OFFSET( _fname ), \
|
||||
FT_FIELD_SIZE_DELTA( _fname ), \
|
||||
_max, \
|
||||
FT_FIELD_OFFSET( num_ ## _fname ), \
|
||||
_dict \
|
||||
},
|
||||
|
||||
#define T1_NEW_TABLE_FIELD2( _ident, _type, _fname, _max ) \
|
||||
{ \
|
||||
_ident, T1CODE, _type, \
|
||||
0, \
|
||||
FT_FIELD_OFFSET( _fname ), \
|
||||
FT_FIELD_SIZE_DELTA( _fname ), \
|
||||
_max, 0 \
|
||||
#define T1_NEW_TABLE_FIELD2( _ident, _type, _fname, _max, _dict ) \
|
||||
{ \
|
||||
_ident, T1CODE, _type, \
|
||||
0, \
|
||||
FT_FIELD_OFFSET( _fname ), \
|
||||
FT_FIELD_SIZE_DELTA( _fname ), \
|
||||
_max, 0, \
|
||||
_dict \
|
||||
},
|
||||
|
||||
|
||||
#define T1_FIELD_BOOL( _ident, _fname ) \
|
||||
T1_NEW_SIMPLE_FIELD( _ident, T1_FIELD_TYPE_BOOL, _fname )
|
||||
#define T1_FIELD_BOOL( _ident, _fname, _dict ) \
|
||||
T1_NEW_SIMPLE_FIELD( _ident, T1_FIELD_TYPE_BOOL, _fname, _dict )
|
||||
|
||||
#define T1_FIELD_NUM( _ident, _fname ) \
|
||||
T1_NEW_SIMPLE_FIELD( _ident, T1_FIELD_TYPE_INTEGER, _fname )
|
||||
#define T1_FIELD_NUM( _ident, _fname, _dict ) \
|
||||
T1_NEW_SIMPLE_FIELD( _ident, T1_FIELD_TYPE_INTEGER, _fname, _dict )
|
||||
|
||||
#define T1_FIELD_FIXED( _ident, _fname ) \
|
||||
T1_NEW_SIMPLE_FIELD( _ident, T1_FIELD_TYPE_FIXED, _fname )
|
||||
#define T1_FIELD_FIXED( _ident, _fname, _dict ) \
|
||||
T1_NEW_SIMPLE_FIELD( _ident, T1_FIELD_TYPE_FIXED, _fname, _dict )
|
||||
|
||||
#define T1_FIELD_FIXED_1000( _ident, _fname ) \
|
||||
T1_NEW_SIMPLE_FIELD( _ident, T1_FIELD_TYPE_FIXED_1000, _fname )
|
||||
#define T1_FIELD_FIXED_1000( _ident, _fname, _dict ) \
|
||||
T1_NEW_SIMPLE_FIELD( _ident, T1_FIELD_TYPE_FIXED_1000, _fname, \
|
||||
_dict )
|
||||
|
||||
#define T1_FIELD_STRING( _ident, _fname ) \
|
||||
T1_NEW_SIMPLE_FIELD( _ident, T1_FIELD_TYPE_STRING, _fname )
|
||||
#define T1_FIELD_STRING( _ident, _fname, _dict ) \
|
||||
T1_NEW_SIMPLE_FIELD( _ident, T1_FIELD_TYPE_STRING, _fname, _dict )
|
||||
|
||||
#define T1_FIELD_KEY( _ident, _fname ) \
|
||||
T1_NEW_SIMPLE_FIELD( _ident, T1_FIELD_TYPE_KEY, _fname )
|
||||
#define T1_FIELD_KEY( _ident, _fname, _dict ) \
|
||||
T1_NEW_SIMPLE_FIELD( _ident, T1_FIELD_TYPE_KEY, _fname, _dict )
|
||||
|
||||
#define T1_FIELD_BBOX( _ident, _fname ) \
|
||||
T1_NEW_SIMPLE_FIELD( _ident, T1_FIELD_TYPE_BBOX, _fname )
|
||||
#define T1_FIELD_BBOX( _ident, _fname, _dict ) \
|
||||
T1_NEW_SIMPLE_FIELD( _ident, T1_FIELD_TYPE_BBOX, _fname, _dict )
|
||||
|
||||
|
||||
#define T1_FIELD_NUM_TABLE( _ident, _fname, _fmax ) \
|
||||
#define T1_FIELD_NUM_TABLE( _ident, _fname, _fmax, _dict ) \
|
||||
T1_NEW_TABLE_FIELD( _ident, T1_FIELD_TYPE_INTEGER_ARRAY, \
|
||||
_fname, _fmax )
|
||||
_fname, _fmax, _dict )
|
||||
|
||||
#define T1_FIELD_FIXED_TABLE( _ident, _fname, _fmax ) \
|
||||
#define T1_FIELD_FIXED_TABLE( _ident, _fname, _fmax, _dict ) \
|
||||
T1_NEW_TABLE_FIELD( _ident, T1_FIELD_TYPE_FIXED_ARRAY, \
|
||||
_fname, _fmax )
|
||||
_fname, _fmax, _dict )
|
||||
|
||||
#define T1_FIELD_NUM_TABLE2( _ident, _fname, _fmax ) \
|
||||
#define T1_FIELD_NUM_TABLE2( _ident, _fname, _fmax, _dict ) \
|
||||
T1_NEW_TABLE_FIELD2( _ident, T1_FIELD_TYPE_INTEGER_ARRAY, \
|
||||
_fname, _fmax )
|
||||
_fname, _fmax, _dict )
|
||||
|
||||
#define T1_FIELD_FIXED_TABLE2( _ident, _fname, _fmax ) \
|
||||
#define T1_FIELD_FIXED_TABLE2( _ident, _fname, _fmax, _dict ) \
|
||||
T1_NEW_TABLE_FIELD2( _ident, T1_FIELD_TYPE_FIXED_ARRAY, \
|
||||
_fname, _fmax )
|
||||
_fname, _fmax, _dict )
|
||||
|
||||
#define T1_FIELD_CALLBACK( _ident, _name ) \
|
||||
T1_NEW_CALLBACK_FIELD( _ident, _name )
|
||||
#define T1_FIELD_CALLBACK( _ident, _name, _dict ) \
|
||||
T1_NEW_CALLBACK_FIELD( _ident, _name, _dict )
|
||||
|
||||
|
||||
/*************************************************************************/
|
||||
@ -683,6 +697,9 @@ FT_BEGIN_HEADER
|
||||
T1_Decoder_Callback parse_callback;
|
||||
T1_Decoder_FuncsRec funcs;
|
||||
|
||||
FT_Int* buildchar;
|
||||
FT_UInt len_buildchar;
|
||||
|
||||
} T1_DecoderRec;
|
||||
|
||||
|
||||
@ -712,8 +729,10 @@ FT_BEGIN_HEADER
|
||||
|
||||
} AFM_Parser_FuncsRec;
|
||||
|
||||
|
||||
typedef struct AFM_StreamRec_* AFM_Stream;
|
||||
|
||||
|
||||
/*************************************************************************/
|
||||
/* */
|
||||
/* <Struct> */
|
||||
@ -801,6 +820,57 @@ FT_BEGIN_HEADER
|
||||
/* backwards-compatible type definition */
|
||||
typedef PSAux_ServiceRec PSAux_Interface;
|
||||
|
||||
|
||||
/*************************************************************************/
|
||||
/*************************************************************************/
|
||||
/***** *****/
|
||||
/***** Some convenience functions *****/
|
||||
/***** *****/
|
||||
/*************************************************************************/
|
||||
/*************************************************************************/
|
||||
|
||||
#define IS_PS_NEWLINE( ch ) \
|
||||
( (ch) == '\r' || \
|
||||
(ch) == '\n' )
|
||||
|
||||
#define IS_PS_SPACE( ch ) \
|
||||
( (ch) == ' ' || \
|
||||
IS_PS_NEWLINE( ch ) || \
|
||||
(ch) == '\t' || \
|
||||
(ch) == '\f' || \
|
||||
(ch) == '\0' )
|
||||
|
||||
#define IS_PS_SPECIAL( ch ) \
|
||||
( (ch) == '/' || \
|
||||
(ch) == '(' || (ch) == ')' || \
|
||||
(ch) == '<' || (ch) == '>' || \
|
||||
(ch) == '[' || (ch) == ']' || \
|
||||
(ch) == '{' || (ch) == '}' || \
|
||||
(ch) == '%' )
|
||||
|
||||
#define IS_PS_DELIM( ch ) \
|
||||
( IS_PS_SPACE( ch ) || \
|
||||
IS_PS_SPECIAL( ch ) )
|
||||
|
||||
#define IS_PS_DIGIT( ch ) \
|
||||
( (ch) >= '0' && (ch) <= '9' )
|
||||
|
||||
#define IS_PS_XDIGIT( ch ) \
|
||||
( IS_PS_DIGIT( ch ) || \
|
||||
( (ch) >= 'A' && (ch) <= 'F' ) || \
|
||||
( (ch) >= 'a' && (ch) <= 'f' ) )
|
||||
|
||||
#define IS_PS_BASE85( ch ) \
|
||||
( (ch) >= '!' && (ch) <= 'u' )
|
||||
|
||||
#define IS_PS_TOKEN( cur, limit, token ) \
|
||||
( (char)(cur)[0] == (token)[0] && \
|
||||
( (cur) + sizeof ( (token) ) == (limit) || \
|
||||
( (cur) + sizeof( (token) ) < (limit) && \
|
||||
IS_PS_DELIM( (cur)[sizeof ( (token) ) - 1] ) ) ) && \
|
||||
ft_strncmp( (char*)(cur), (token), sizeof ( (token) ) - 1 ) == 0 )
|
||||
|
||||
|
||||
FT_END_HEADER
|
||||
|
||||
#endif /* __PSAUX_H__ */
|
||||
|
@ -36,12 +36,12 @@ FT_BEGIN_HEADER
|
||||
|
||||
FT_DEFINE_SERVICE( Kerning )
|
||||
{
|
||||
FT_Kerning_TrackGetFunc get_track;
|
||||
FT_Kerning_TrackGetFunc get_track;
|
||||
};
|
||||
|
||||
/* */
|
||||
|
||||
|
||||
|
||||
FT_END_HEADER
|
||||
|
||||
|
||||
|
@ -29,13 +29,13 @@ FT_BEGIN_HEADER
|
||||
|
||||
|
||||
typedef FT_Error
|
||||
(*otv_validate_func)( FT_Face face,
|
||||
FT_UInt ot_flags,
|
||||
FT_Bytes *base,
|
||||
FT_Bytes *gdef,
|
||||
FT_Bytes *gpos,
|
||||
FT_Bytes *gsub,
|
||||
FT_Bytes *jstf );
|
||||
(*otv_validate_func)( FT_Face volatile face,
|
||||
FT_UInt ot_flags,
|
||||
FT_Bytes *base,
|
||||
FT_Bytes *gdef,
|
||||
FT_Bytes *gpos,
|
||||
FT_Bytes *gsub,
|
||||
FT_Bytes *jstf );
|
||||
|
||||
|
||||
FT_DEFINE_SERVICE( OTvalidate )
|
||||
|
@ -75,15 +75,24 @@ FT_BEGIN_HEADER
|
||||
* NULL if invalid index.
|
||||
*/
|
||||
typedef const char*
|
||||
(*PS_Glyph_NameFunc)( FT_Pointer data,
|
||||
FT_UInt string_index );
|
||||
(*PS_GetGlyphNameFunc)( FT_Pointer data,
|
||||
FT_UInt string_index );
|
||||
|
||||
/*
|
||||
* A function used to release the glyph name returned by
|
||||
* PS_GetGlyphNameFunc, when needed
|
||||
*/
|
||||
typedef void
|
||||
(*PS_FreeGlyphNameFunc)( FT_Pointer data,
|
||||
const char* name );
|
||||
|
||||
typedef FT_Error
|
||||
(*PS_Unicodes_InitFunc)( FT_Memory memory,
|
||||
PS_Unicodes unicodes,
|
||||
FT_UInt num_glyphs,
|
||||
PS_Glyph_NameFunc get_glyph_name,
|
||||
FT_Pointer glyph_data );
|
||||
(*PS_Unicodes_InitFunc)( FT_Memory memory,
|
||||
PS_Unicodes unicodes,
|
||||
FT_UInt num_glyphs,
|
||||
PS_GetGlyphNameFunc get_glyph_name,
|
||||
PS_FreeGlyphNameFunc free_glyph_name,
|
||||
FT_Pointer glyph_data );
|
||||
|
||||
typedef FT_UInt
|
||||
(*PS_Unicodes_CharIndexFunc)( PS_Unicodes unicodes,
|
||||
|
@ -18,11 +18,11 @@
|
||||
/* */
|
||||
/***************************************************************************/
|
||||
|
||||
/* Development of this service is support of
|
||||
/* Development of this service is support of
|
||||
Information-technology Promotion Agency, Japan. */
|
||||
|
||||
#ifndef __SVTTCMAP_H__
|
||||
#define __SVTTCMAP_H__
|
||||
#define __SVTTCMAP_H__
|
||||
|
||||
#include FT_INTERNAL_SERVICE_H
|
||||
#include FT_TRUETYPE_TABLES_H
|
||||
@ -64,8 +64,8 @@ FT_BEGIN_HEADER
|
||||
FT_DEFINE_SERVICE( TTCMaps )
|
||||
{
|
||||
TT_CMap_Info_GetFunc get_cmap_info;
|
||||
};
|
||||
|
||||
};
|
||||
|
||||
/* */
|
||||
|
||||
|
||||
|
@ -45,7 +45,7 @@ FT_BEGIN_HEADER
|
||||
|
||||
/* */
|
||||
|
||||
|
||||
|
||||
FT_END_HEADER
|
||||
|
||||
|
||||
|
@ -738,13 +738,13 @@ FT_BEGIN_HEADER
|
||||
/* the table directory */
|
||||
TT_Load_Table_Func load_font_dir;
|
||||
TT_Load_Metrics_Func load_hmtx;
|
||||
|
||||
|
||||
TT_Load_Table_Func load_eblc;
|
||||
TT_Free_Table_Func free_eblc;
|
||||
|
||||
|
||||
TT_Set_SBit_Strike_Func set_sbit_strike;
|
||||
TT_Load_Strike_Metrics_Func load_strike_metrics;
|
||||
|
||||
|
||||
TT_Get_Metrics_Func get_metrics;
|
||||
|
||||
} SFNT_Interface;
|
||||
|
@ -203,11 +203,22 @@ FT_BEGIN_HEADER
|
||||
|
||||
#ifdef FT_CONFIG_OPTION_OLD_INTERNALS
|
||||
PS_Unicodes unicode_map;
|
||||
#endif
|
||||
#endif
|
||||
|
||||
/* support for Multiple Masters fonts */
|
||||
PS_Blend blend;
|
||||
|
||||
/* undocumented, optional: indices of subroutines that express */
|
||||
/* the NormalizeDesignVector and the ConvertDesignVector procedure, */
|
||||
/* respectively, as Type 2 charstrings; -1 if keywords not present */
|
||||
FT_Int ndv_idx;
|
||||
FT_Int cdv_idx;
|
||||
|
||||
/* undocumented, optional: has the same meaning as len_buildchar */
|
||||
/* for Type 2 fonts; manipulated by othersubrs 19, 24, and 25 */
|
||||
FT_UInt len_buildchar;
|
||||
FT_Int* buildchar;
|
||||
|
||||
/* since version 2.1 - interface to PostScript hinter */
|
||||
const void* pshinter;
|
||||
|
||||
|
@ -5,7 +5,7 @@
|
||||
/* Basic SFNT/TrueType type definitions and interface (specification */
|
||||
/* only). */
|
||||
/* */
|
||||
/* Copyright 1996-2001, 2002, 2004, 2005, 2006 by */
|
||||
/* Copyright 1996-2001, 2002, 2004, 2005, 2006, 2007 by */
|
||||
/* David Turner, Robert Wilhelm, and Werner Lemberg. */
|
||||
/* */
|
||||
/* This file is part of the FreeType project, and may only be used, */
|
||||
@ -1395,7 +1395,6 @@ FT_BEGIN_HEADER
|
||||
|
||||
/* since version 2.2 */
|
||||
|
||||
#ifdef FT_OPTIMIZE_MEMORY
|
||||
FT_Byte* horz_metrics;
|
||||
FT_ULong horz_metrics_size;
|
||||
|
||||
@ -1420,12 +1419,15 @@ FT_BEGIN_HEADER
|
||||
FT_UInt num_kern_tables;
|
||||
FT_UInt32 kern_avail_bits;
|
||||
FT_UInt32 kern_order_bits;
|
||||
#endif
|
||||
|
||||
#ifdef TT_CONFIG_OPTION_BDF
|
||||
TT_BDFRec bdf;
|
||||
#endif /* TT_CONFIG_OPTION_BDF */
|
||||
|
||||
/* since 2.3.0 */
|
||||
FT_ULong horz_metrics_offset;
|
||||
FT_ULong vert_metrics_offset;
|
||||
|
||||
} TT_FaceRec;
|
||||
|
||||
|
||||
@ -1458,19 +1460,24 @@ FT_BEGIN_HEADER
|
||||
/* */
|
||||
/* contours :: The contours end points. */
|
||||
/* */
|
||||
/* first_point :: Offset of the current subglyph's first point. */
|
||||
/* */
|
||||
typedef struct TT_GlyphZoneRec_
|
||||
{
|
||||
FT_Memory memory;
|
||||
FT_UShort max_points;
|
||||
FT_UShort max_contours;
|
||||
FT_UShort n_points; /* number of points in zone */
|
||||
FT_Short n_contours; /* number of contours */
|
||||
FT_UShort n_points; /* number of points in zone */
|
||||
FT_Short n_contours; /* number of contours */
|
||||
|
||||
FT_Vector* org; /* original point coordinates */
|
||||
FT_Vector* cur; /* current point coordinates */
|
||||
FT_Vector* org; /* original point coordinates */
|
||||
FT_Vector* cur; /* current point coordinates */
|
||||
FT_Vector* orus; /* original (unscaled) point coordinates */
|
||||
|
||||
FT_Byte* tags; /* current touch flags */
|
||||
FT_UShort* contours; /* contour end points */
|
||||
FT_Byte* tags; /* current touch flags */
|
||||
FT_UShort* contours; /* contour end points */
|
||||
|
||||
FT_UShort first_point; /* offset of first (#0) point */
|
||||
|
||||
} TT_GlyphZoneRec, *TT_GlyphZone;
|
||||
|
||||
@ -1521,6 +1528,10 @@ FT_BEGIN_HEADER
|
||||
FT_Vector pp3;
|
||||
FT_Vector pp4;
|
||||
|
||||
/* since version 2.2.1 */
|
||||
FT_Byte* cursor;
|
||||
FT_Byte* limit;
|
||||
|
||||
} TT_LoaderRec;
|
||||
|
||||
|
||||
|
@ -5,7 +5,7 @@
|
||||
/* Basic Type 1/Type 2 tables definitions and interface (specification */
|
||||
/* only). */
|
||||
/* */
|
||||
/* Copyright 1996-2001, 2002, 2003, 2004 by */
|
||||
/* Copyright 1996-2001, 2002, 2003, 2004, 2006 by */
|
||||
/* David Turner, Robert Wilhelm, and Werner Lemberg. */
|
||||
/* */
|
||||
/* This file is part of the FreeType project, and may only be used, */
|
||||
@ -256,6 +256,15 @@ FT_BEGIN_HEADER
|
||||
|
||||
FT_BBox* bboxes [T1_MAX_MM_DESIGNS + 1];
|
||||
|
||||
/* since 2.3.0 */
|
||||
|
||||
/* undocumented, optional: the default design instance; */
|
||||
/* corresponds to default_weight_vector -- */
|
||||
/* num_default_design_vector == 0 means it is not present */
|
||||
/* in the font and associated metrics files */
|
||||
FT_UInt default_design_vector[T1_MAX_MM_DESIGNS];
|
||||
FT_UInt num_default_design_vector;
|
||||
|
||||
} PS_BlendRec, *PS_Blend;
|
||||
|
||||
|
||||
|
@ -619,7 +619,7 @@ FT_BEGIN_HEADER
|
||||
* to access the whole font file. Otherwise, you can use one of the
|
||||
* definitions found in the @FT_TRUETYPE_TAGS_H file, or forge a new
|
||||
* one with @FT_MAKE_TAG.
|
||||
*
|
||||
*
|
||||
* offset ::
|
||||
* The starting offset in the table (or file if tag == 0).
|
||||
*
|
||||
@ -630,7 +630,7 @@ FT_BEGIN_HEADER
|
||||
*
|
||||
* @inout:
|
||||
* length ::
|
||||
* If the `length' parameter is NULL, then try to load the whole table.
|
||||
* If the `length' parameter is NULL, then try to load the whole table.
|
||||
* Return an error code if it fails.
|
||||
*
|
||||
* Else, if `*length' is 0, exit immediately while returning the
|
||||
|
@ -5,7 +5,7 @@
|
||||
/* Routines used to compute vector angles with limited accuracy */
|
||||
/* and very high speed. It also contains sorting routines (body). */
|
||||
/* */
|
||||
/* Copyright 2003, 2004, 2005 by */
|
||||
/* Copyright 2003, 2004, 2005, 2006 by */
|
||||
/* David Turner, Robert Wilhelm, and Werner Lemberg. */
|
||||
/* */
|
||||
/* This file is part of the FreeType project, and may only be used, */
|
||||
@ -20,7 +20,123 @@
|
||||
#include "aftypes.h"
|
||||
|
||||
|
||||
#if 1
|
||||
#if 0
|
||||
|
||||
FT_LOCAL_DEF( FT_Int )
|
||||
af_corner_is_flat( FT_Pos x_in,
|
||||
FT_Pos y_in,
|
||||
FT_Pos x_out,
|
||||
FT_Pos y_out )
|
||||
{
|
||||
FT_Pos ax = x_in;
|
||||
FT_Pos ay = y_in;
|
||||
|
||||
FT_Pos d_in, d_out, d_corner;
|
||||
|
||||
|
||||
if ( ax < 0 )
|
||||
ax = -ax;
|
||||
if ( ay < 0 )
|
||||
ay = -ay;
|
||||
d_in = ax + ay;
|
||||
|
||||
ax = x_out;
|
||||
if ( ax < 0 )
|
||||
ax = -ax;
|
||||
ay = y_out;
|
||||
if ( ay < 0 )
|
||||
ay = -ay;
|
||||
d_out = ax + ay;
|
||||
|
||||
ax = x_out + x_in;
|
||||
if ( ax < 0 )
|
||||
ax = -ax;
|
||||
ay = y_out + y_in;
|
||||
if ( ay < 0 )
|
||||
ay = -ay;
|
||||
d_corner = ax + ay;
|
||||
|
||||
return ( d_in + d_out - d_corner ) < ( d_corner >> 4 );
|
||||
}
|
||||
|
||||
|
||||
FT_LOCAL_DEF( FT_Int )
|
||||
af_corner_orientation( FT_Pos x_in,
|
||||
FT_Pos y_in,
|
||||
FT_Pos x_out,
|
||||
FT_Pos y_out )
|
||||
{
|
||||
FT_Pos delta;
|
||||
|
||||
|
||||
delta = x_in * y_out - y_in * x_out;
|
||||
|
||||
if ( delta == 0 )
|
||||
return 0;
|
||||
else
|
||||
return 1 - 2 * ( delta < 0 );
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
/*
|
||||
* We are not using `af_angle_atan' anymore, but we keep the source
|
||||
* code below just in case...
|
||||
*/
|
||||
|
||||
|
||||
#if 0
|
||||
|
||||
|
||||
/*
|
||||
* The trick here is to realize that we don't need a very accurate angle
|
||||
* approximation. We are going to use the result of `af_angle_atan' to
|
||||
* only compare the sign of angle differences, or check whether its
|
||||
* magnitude is very small.
|
||||
*
|
||||
* The approximation
|
||||
*
|
||||
* dy * PI / (|dx|+|dy|)
|
||||
*
|
||||
* should be enough, and much faster to compute.
|
||||
*/
|
||||
FT_LOCAL_DEF( AF_Angle )
|
||||
af_angle_atan( FT_Fixed dx,
|
||||
FT_Fixed dy )
|
||||
{
|
||||
AF_Angle angle;
|
||||
FT_Fixed ax = dx;
|
||||
FT_Fixed ay = dy;
|
||||
|
||||
|
||||
if ( ax < 0 )
|
||||
ax = -ax;
|
||||
if ( ay < 0 )
|
||||
ay = -ay;
|
||||
|
||||
ax += ay;
|
||||
|
||||
if ( ax == 0 )
|
||||
angle = 0;
|
||||
else
|
||||
{
|
||||
angle = ( AF_ANGLE_PI2 * dy ) / ( ax + ay );
|
||||
if ( dx < 0 )
|
||||
{
|
||||
if ( angle >= 0 )
|
||||
angle = AF_ANGLE_PI - angle;
|
||||
else
|
||||
angle = -AF_ANGLE_PI - angle;
|
||||
}
|
||||
}
|
||||
|
||||
return angle;
|
||||
}
|
||||
|
||||
|
||||
#elif 0
|
||||
|
||||
|
||||
/* the following table has been automatically generated with */
|
||||
/* the `mather.py' Python script */
|
||||
@ -124,222 +240,6 @@
|
||||
}
|
||||
|
||||
|
||||
#else /* 0 */
|
||||
|
||||
/*
|
||||
* a python script used to generate the following table
|
||||
*
|
||||
|
||||
import sys, math
|
||||
|
||||
units = 256
|
||||
scale = units/math.pi
|
||||
comma = ""
|
||||
|
||||
print ""
|
||||
print "table of arctan( 1/2^n ) for PI = " + repr( units / 65536.0 ) + " units"
|
||||
|
||||
r = [-1] + range( 32 )
|
||||
|
||||
for n in r:
|
||||
if n >= 0:
|
||||
x = 1.0 / ( 2.0 ** n ) # tangent value
|
||||
else:
|
||||
x = 2.0 ** ( -n )
|
||||
|
||||
angle = math.atan( x ) # arctangent
|
||||
angle2 = angle * scale # arctangent in FT_Angle units
|
||||
|
||||
# determine which integer value for angle gives the best tangent
|
||||
lo = int( angle2 )
|
||||
hi = lo + 1
|
||||
tlo = math.tan( lo / scale )
|
||||
thi = math.tan( hi / scale )
|
||||
|
||||
errlo = abs( tlo - x )
|
||||
errhi = abs( thi - x )
|
||||
|
||||
angle2 = hi
|
||||
if errlo < errhi:
|
||||
angle2 = lo
|
||||
|
||||
if angle2 <= 0:
|
||||
break
|
||||
|
||||
sys.stdout.write( comma + repr( int( angle2 ) ) )
|
||||
comma = ", "
|
||||
|
||||
*
|
||||
* end of python script
|
||||
*/
|
||||
|
||||
|
||||
/* this table was generated for AF_ANGLE_PI = 256 */
|
||||
#define AF_ANGLE_MAX_ITERS 8
|
||||
#define AF_TRIG_MAX_ITERS 8
|
||||
|
||||
static const FT_Fixed
|
||||
af_angle_arctan_table[9] =
|
||||
{
|
||||
90, 64, 38, 20, 10, 5, 3, 1, 1
|
||||
};
|
||||
|
||||
|
||||
static FT_Int
|
||||
af_angle_prenorm( FT_Vector* vec )
|
||||
{
|
||||
FT_Fixed x, y, z;
|
||||
FT_Int shift;
|
||||
|
||||
|
||||
x = vec->x;
|
||||
y = vec->y;
|
||||
|
||||
z = ( ( x >= 0 ) ? x : - x ) | ( (y >= 0) ? y : -y );
|
||||
shift = 0;
|
||||
|
||||
if ( z < ( 1L << 27 ) )
|
||||
{
|
||||
do
|
||||
{
|
||||
shift++;
|
||||
z <<= 1;
|
||||
} while ( z < ( 1L << 27 ) );
|
||||
|
||||
vec->x = x << shift;
|
||||
vec->y = y << shift;
|
||||
}
|
||||
else if ( z > ( 1L << 28 ) )
|
||||
{
|
||||
do
|
||||
{
|
||||
shift++;
|
||||
z >>= 1;
|
||||
} while ( z > ( 1L << 28 ) );
|
||||
|
||||
vec->x = x >> shift;
|
||||
vec->y = y >> shift;
|
||||
shift = -shift;
|
||||
}
|
||||
return shift;
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
af_angle_pseudo_polarize( FT_Vector* vec )
|
||||
{
|
||||
FT_Fixed theta;
|
||||
FT_Fixed yi, i;
|
||||
FT_Fixed x, y;
|
||||
const FT_Fixed *arctanptr;
|
||||
|
||||
|
||||
x = vec->x;
|
||||
y = vec->y;
|
||||
|
||||
/* Get the vector into the right half plane */
|
||||
theta = 0;
|
||||
if ( x < 0 )
|
||||
{
|
||||
x = -x;
|
||||
y = -y;
|
||||
theta = AF_ANGLE_PI;
|
||||
}
|
||||
|
||||
if ( y > 0 )
|
||||
theta = -theta;
|
||||
|
||||
arctanptr = af_angle_arctan_table;
|
||||
|
||||
if ( y < 0 )
|
||||
{
|
||||
/* Rotate positive */
|
||||
yi = y + ( x << 1 );
|
||||
x = x - ( y << 1 );
|
||||
y = yi;
|
||||
theta -= *arctanptr++; /* Subtract angle */
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Rotate negative */
|
||||
yi = y - ( x << 1 );
|
||||
x = x + ( y << 1 );
|
||||
y = yi;
|
||||
theta += *arctanptr++; /* Add angle */
|
||||
}
|
||||
|
||||
i = 0;
|
||||
do
|
||||
{
|
||||
if ( y < 0 )
|
||||
{
|
||||
/* Rotate positive */
|
||||
yi = y + ( x >> i );
|
||||
x = x - ( y >> i );
|
||||
y = yi;
|
||||
theta -= *arctanptr++;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Rotate negative */
|
||||
yi = y - ( x >> i );
|
||||
x = x + ( y >> i );
|
||||
y = yi;
|
||||
theta += *arctanptr++;
|
||||
}
|
||||
} while ( ++i < AF_TRIG_MAX_ITERS );
|
||||
|
||||
#if 0
|
||||
/* round theta */
|
||||
if ( theta >= 0 )
|
||||
theta = FT_PAD_ROUND( theta, 2 );
|
||||
else
|
||||
theta = -FT_PAD_ROUND( -theta, 2 );
|
||||
#endif
|
||||
|
||||
vec->x = x;
|
||||
vec->y = theta;
|
||||
}
|
||||
|
||||
|
||||
/* cf. documentation in fttrigon.h */
|
||||
|
||||
FT_LOCAL_DEF( AF_Angle )
|
||||
af_angle_atan( FT_Fixed dx,
|
||||
FT_Fixed dy )
|
||||
{
|
||||
FT_Vector v;
|
||||
|
||||
|
||||
if ( dx == 0 && dy == 0 )
|
||||
return 0;
|
||||
|
||||
v.x = dx;
|
||||
v.y = dy;
|
||||
af_angle_prenorm( &v );
|
||||
af_angle_pseudo_polarize( &v );
|
||||
|
||||
return v.y;
|
||||
}
|
||||
|
||||
|
||||
FT_LOCAL_DEF( AF_Angle )
|
||||
af_angle_diff( AF_Angle angle1,
|
||||
AF_Angle angle2 )
|
||||
{
|
||||
AF_Angle delta = angle2 - angle1;
|
||||
|
||||
|
||||
delta %= AF_ANGLE_2PI;
|
||||
if ( delta < 0 )
|
||||
delta += AF_ANGLE_2PI;
|
||||
|
||||
if ( delta > AF_ANGLE_PI )
|
||||
delta -= AF_ANGLE_2PI;
|
||||
|
||||
return delta;
|
||||
}
|
||||
|
||||
#endif /* 0 */
|
||||
|
||||
|
||||
@ -389,45 +289,4 @@ for n in r:
|
||||
}
|
||||
|
||||
|
||||
#ifdef TEST
|
||||
|
||||
#include <stdio.h>
|
||||
#include <math.h>
|
||||
|
||||
int main( void )
|
||||
{
|
||||
int angle;
|
||||
int dist;
|
||||
|
||||
|
||||
for ( dist = 100; dist < 1000; dist++ )
|
||||
{
|
||||
for ( angle = AF_ANGLE_PI; angle < AF_ANGLE_2PI * 4; angle++ )
|
||||
{
|
||||
double a = ( angle * 3.1415926535 ) / ( 1.0 * AF_ANGLE_PI );
|
||||
int dx, dy, angle1, angle2, delta;
|
||||
|
||||
|
||||
dx = dist * cos( a );
|
||||
dy = dist * sin( a );
|
||||
|
||||
angle1 = ( ( atan2( dy, dx ) * AF_ANGLE_PI ) / 3.1415926535 );
|
||||
angle2 = af_angle_atan( dx, dy );
|
||||
delta = ( angle2 - angle1 ) % AF_ANGLE_2PI;
|
||||
if ( delta < 0 )
|
||||
delta = -delta;
|
||||
|
||||
if ( delta >= 2 )
|
||||
{
|
||||
printf( "dist:%4d angle:%4d => (%4d,%4d) angle1:%4d angle2:%4d\n",
|
||||
dist, angle, dx, dy, angle1, angle2 );
|
||||
}
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
#endif /* TEST */
|
||||
|
||||
|
||||
/* END */
|
||||
|
@ -1437,7 +1437,9 @@
|
||||
|
||||
static const AF_Script_UniRangeRec af_cjk_uniranges[] =
|
||||
{
|
||||
{ 0x0100, 0xFFFF },
|
||||
#if 0
|
||||
{ 0x0100, 0xFFFF }, /* why this? */
|
||||
#endif
|
||||
{ 0x2E80, 0x2EFF }, /* CJK Radicals Supplement */
|
||||
{ 0x2F00, 0x2FDF }, /* Kangxi Radicals */
|
||||
{ 0x3000, 0x303F }, /* CJK Symbols and Punctuation */
|
||||
|
@ -4,7 +4,7 @@
|
||||
/* */
|
||||
/* Auto-fitter hinting routines (body). */
|
||||
/* */
|
||||
/* Copyright 2003, 2004, 2005, 2006 by */
|
||||
/* Copyright 2003, 2004, 2005, 2006, 2007 by */
|
||||
/* David Turner, Robert Wilhelm, and Werner Lemberg. */
|
||||
/* */
|
||||
/* This file is part of the FreeType project, and may only be used, */
|
||||
@ -18,6 +18,7 @@
|
||||
|
||||
#include "afhints.h"
|
||||
#include "aferrors.h"
|
||||
#include FT_INTERNAL_CALC_H
|
||||
|
||||
|
||||
FT_LOCAL_DEF( FT_Error )
|
||||
@ -53,7 +54,9 @@
|
||||
}
|
||||
|
||||
segment = axis->segments + axis->num_segments++;
|
||||
#if 0
|
||||
FT_ZERO( segment );
|
||||
#endif
|
||||
|
||||
Exit:
|
||||
*asegment = segment;
|
||||
@ -188,8 +191,7 @@
|
||||
void
|
||||
af_glyph_hints_dump_segments( AF_GlyphHints hints )
|
||||
{
|
||||
AF_Point points = hints->points;
|
||||
FT_Int dimension;
|
||||
FT_Int dimension;
|
||||
|
||||
|
||||
for ( dimension = 1; dimension >= 0; dimension-- )
|
||||
@ -203,19 +205,18 @@
|
||||
printf ( "Table of %s segments:\n",
|
||||
dimension == AF_DIMENSION_HORZ ? "vertical" : "horizontal" );
|
||||
printf ( " [ index | pos | dir | link | serif |"
|
||||
" numl | first | start ]\n" );
|
||||
" height | extra ]\n" );
|
||||
|
||||
for ( seg = segments; seg < limit; seg++ )
|
||||
{
|
||||
printf ( " [ %5d | %4d | %5s | %4d | %5d | %4d | %5d | %5d ]\n",
|
||||
printf ( " [ %5d | %4d | %5s | %4d | %5d | %5d | %5d ]\n",
|
||||
seg - segments,
|
||||
(int)seg->pos,
|
||||
af_dir_str( seg->dir ),
|
||||
af_dir_str( (AF_Direction)seg->dir ),
|
||||
AF_INDEX_NUM( seg->link, segments ),
|
||||
AF_INDEX_NUM( seg->serif, segments ),
|
||||
(int)seg->num_linked,
|
||||
seg->first - points,
|
||||
seg->last - points );
|
||||
seg->height,
|
||||
seg->height - ( seg->max_coord - seg->min_coord ) );
|
||||
}
|
||||
printf( "\n" );
|
||||
}
|
||||
@ -251,7 +252,7 @@
|
||||
" %5d | %c | %5.2f | %5.2f ]\n",
|
||||
edge - edges,
|
||||
(int)edge->fpos,
|
||||
af_dir_str( edge->dir ),
|
||||
af_dir_str( (AF_Direction)edge->dir ),
|
||||
AF_INDEX_NUM( edge->link, edges ),
|
||||
AF_INDEX_NUM( edge->serif, edges ),
|
||||
edge->blue_edge ? 'y' : 'n',
|
||||
@ -262,8 +263,32 @@
|
||||
}
|
||||
}
|
||||
|
||||
#endif /* AF_DEBUG */
|
||||
#else /* !AF_DEBUG */
|
||||
|
||||
/* these empty stubs are only used to link the `ftgrid' test program */
|
||||
/* when debugging is disabled */
|
||||
|
||||
void
|
||||
af_glyph_hints_dump_points( AF_GlyphHints hints )
|
||||
{
|
||||
FT_UNUSED( hints );
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
af_glyph_hints_dump_segments( AF_GlyphHints hints )
|
||||
{
|
||||
FT_UNUSED( hints );
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
af_glyph_hints_dump_edges( AF_GlyphHints hints )
|
||||
{
|
||||
FT_UNUSED( hints );
|
||||
}
|
||||
|
||||
#endif /* !AF_DEBUG */
|
||||
|
||||
|
||||
/* compute the direction value of a given vector */
|
||||
@ -271,51 +296,48 @@
|
||||
af_direction_compute( FT_Pos dx,
|
||||
FT_Pos dy )
|
||||
{
|
||||
|
||||
#if 1
|
||||
AF_Direction dir = AF_DIR_NONE;
|
||||
|
||||
FT_Pos ll, ss; /* long and short arm lengths */
|
||||
AF_Direction dir; /* candidate direction */
|
||||
|
||||
|
||||
/* atan(1/12) == 4.7 degrees */
|
||||
|
||||
if ( dx < 0 )
|
||||
if ( dy >= dx )
|
||||
{
|
||||
if ( dy < 0 )
|
||||
if ( dy >= -dx )
|
||||
{
|
||||
if ( -dx * 12 < -dy )
|
||||
dir = AF_DIR_DOWN;
|
||||
|
||||
else if ( -dy * 12 < -dx )
|
||||
dir = AF_DIR_LEFT;
|
||||
dir = AF_DIR_UP;
|
||||
ll = dy;
|
||||
ss = dx;
|
||||
}
|
||||
else /* dy >= 0 */
|
||||
else
|
||||
{
|
||||
if ( -dx * 12 < dy )
|
||||
dir = AF_DIR_UP;
|
||||
|
||||
else if ( dy * 12 < -dx )
|
||||
dir = AF_DIR_LEFT;
|
||||
dir = AF_DIR_LEFT;
|
||||
ll = -dx;
|
||||
ss = dy;
|
||||
}
|
||||
}
|
||||
else /* dx >= 0 */
|
||||
else /* dy < dx */
|
||||
{
|
||||
if ( dy < 0 )
|
||||
if ( dy >= -dx )
|
||||
{
|
||||
if ( dx * 12 < -dy )
|
||||
dir = AF_DIR_DOWN;
|
||||
|
||||
else if ( -dy * 12 < dx )
|
||||
dir = AF_DIR_RIGHT;
|
||||
dir = AF_DIR_RIGHT;
|
||||
ll = dx;
|
||||
ss = dy;
|
||||
}
|
||||
else /* dy >= 0 */
|
||||
else
|
||||
{
|
||||
if ( dx * 12 < dy )
|
||||
dir = AF_DIR_UP;
|
||||
|
||||
else if ( dy * 12 < dx )
|
||||
dir = AF_DIR_RIGHT;
|
||||
dir = AF_DIR_DOWN;
|
||||
ll = dy;
|
||||
ss = dx;
|
||||
}
|
||||
}
|
||||
|
||||
ss *= 12;
|
||||
if ( FT_ABS(ll) <= FT_ABS(ss) )
|
||||
dir = AF_DIR_NONE;
|
||||
|
||||
return dir;
|
||||
|
||||
#else /* 0 */
|
||||
@ -348,6 +370,122 @@
|
||||
|
||||
|
||||
/* compute all inflex points in a given glyph */
|
||||
|
||||
#if 1
|
||||
|
||||
static void
|
||||
af_glyph_hints_compute_inflections( AF_GlyphHints hints )
|
||||
{
|
||||
AF_Point* contour = hints->contours;
|
||||
AF_Point* contour_limit = contour + hints->num_contours;
|
||||
|
||||
|
||||
/* do each contour separately */
|
||||
for ( ; contour < contour_limit; contour++ )
|
||||
{
|
||||
AF_Point point = contour[0];
|
||||
AF_Point first = point;
|
||||
AF_Point start = point;
|
||||
AF_Point end = point;
|
||||
AF_Point before;
|
||||
AF_Point after;
|
||||
FT_Pos in_x, in_y, out_x, out_y;
|
||||
AF_Angle orient_prev, orient_cur;
|
||||
FT_Int finished = 0;
|
||||
|
||||
|
||||
/* compute first segment in contour */
|
||||
first = point;
|
||||
|
||||
start = end = first;
|
||||
do
|
||||
{
|
||||
end = end->next;
|
||||
if ( end == first )
|
||||
goto Skip;
|
||||
|
||||
in_x = end->fx - start->fx;
|
||||
in_y = end->fy - start->fy;
|
||||
|
||||
} while ( in_x == 0 && in_y == 0 );
|
||||
|
||||
/* extend the segment start whenever possible */
|
||||
before = start;
|
||||
do
|
||||
{
|
||||
do
|
||||
{
|
||||
start = before;
|
||||
before = before->prev;
|
||||
if ( before == first )
|
||||
goto Skip;
|
||||
|
||||
out_x = start->fx - before->fx;
|
||||
out_y = start->fy - before->fy;
|
||||
|
||||
} while ( out_x == 0 && out_y == 0 );
|
||||
|
||||
orient_prev = ft_corner_orientation( in_x, in_y, out_x, out_y );
|
||||
|
||||
} while ( orient_prev == 0 );
|
||||
|
||||
first = start;
|
||||
|
||||
in_x = out_x;
|
||||
in_y = out_y;
|
||||
|
||||
/* now process all segments in the contour */
|
||||
do
|
||||
{
|
||||
/* first, extend current segment's end whenever possible */
|
||||
after = end;
|
||||
do
|
||||
{
|
||||
do
|
||||
{
|
||||
end = after;
|
||||
after = after->next;
|
||||
if ( after == first )
|
||||
finished = 1;
|
||||
|
||||
out_x = after->fx - end->fx;
|
||||
out_y = after->fy - end->fy;
|
||||
|
||||
} while ( out_x == 0 && out_y == 0 );
|
||||
|
||||
orient_cur = ft_corner_orientation( in_x, in_y, out_x, out_y );
|
||||
|
||||
} while ( orient_cur == 0 );
|
||||
|
||||
if ( ( orient_prev + orient_cur ) == 0 )
|
||||
{
|
||||
/* we have an inflection point here */
|
||||
do
|
||||
{
|
||||
start->flags |= AF_FLAG_INFLECTION;
|
||||
start = start->next;
|
||||
|
||||
} while ( start != end );
|
||||
|
||||
start->flags |= AF_FLAG_INFLECTION;
|
||||
}
|
||||
|
||||
start = end;
|
||||
end = after;
|
||||
|
||||
orient_prev = orient_cur;
|
||||
in_x = out_x;
|
||||
in_y = out_y;
|
||||
|
||||
} while ( !finished );
|
||||
|
||||
Skip:
|
||||
;
|
||||
}
|
||||
}
|
||||
|
||||
#else /* old code */
|
||||
|
||||
static void
|
||||
af_glyph_hints_compute_inflections( AF_GlyphHints hints )
|
||||
{
|
||||
@ -455,6 +593,8 @@
|
||||
}
|
||||
}
|
||||
|
||||
#endif /* old code */
|
||||
|
||||
|
||||
FT_LOCAL_DEF( void )
|
||||
af_glyph_hints_init( AF_GlyphHints hints,
|
||||
@ -702,6 +842,17 @@
|
||||
}
|
||||
else if ( point->out_dir == point->in_dir )
|
||||
{
|
||||
|
||||
#if 1
|
||||
|
||||
if ( point->out_dir != AF_DIR_NONE )
|
||||
goto Is_Weak_Point;
|
||||
|
||||
if ( ft_corner_is_flat( in_x, in_y, out_x, out_y ) )
|
||||
goto Is_Weak_Point;
|
||||
|
||||
#else /* old code */
|
||||
|
||||
AF_Angle angle_in, angle_out, delta;
|
||||
|
||||
|
||||
@ -715,6 +866,9 @@
|
||||
|
||||
if ( delta < 2 && delta > -2 )
|
||||
goto Is_Weak_Point;
|
||||
|
||||
#endif /* old code */
|
||||
|
||||
}
|
||||
else if ( point->in_dir == -point->out_dir )
|
||||
goto Is_Weak_Point;
|
||||
@ -1152,7 +1306,7 @@
|
||||
AF_Point points = hints->points;
|
||||
AF_Point points_limit = points + hints->num_points;
|
||||
AF_Point point;
|
||||
|
||||
|
||||
|
||||
if ( dim == AF_DIMENSION_HORZ )
|
||||
{
|
||||
|
@ -125,6 +125,7 @@ FT_BEGIN_HEADER
|
||||
FT_Short pos; /* position of segment */
|
||||
FT_Short min_coord; /* minimum coordinate of segment */
|
||||
FT_Short max_coord; /* maximum coordinate of segment */
|
||||
FT_Short height; /* the hinted segment height */
|
||||
|
||||
AF_Edge edge; /* the segment's parent edge */
|
||||
AF_Segment edge_next; /* link to next segment in parent edge */
|
||||
@ -213,6 +214,24 @@ FT_BEGIN_HEADER
|
||||
#define AF_HINTS_TEST_SCALER( h, f ) ( (h)->scaler_flags & (f) )
|
||||
#define AF_HINTS_TEST_OTHER( h, f ) ( (h)->other_flags & (f) )
|
||||
|
||||
|
||||
#ifdef AF_DEBUG
|
||||
|
||||
#define AF_HINTS_DO_HORIZONTAL( h ) \
|
||||
( !_af_debug_disable_horz_hints && \
|
||||
!AF_HINTS_TEST_SCALER( h, AF_SCALER_FLAG_NO_HORIZONTAL ) )
|
||||
|
||||
#define AF_HINTS_DO_VERTICAL( h ) \
|
||||
( !_af_debug_disable_vert_hints && \
|
||||
!AF_HINTS_TEST_SCALER( h, AF_SCALER_FLAG_NO_VERTICAL ) )
|
||||
|
||||
#define AF_HINTS_DO_ADVANCE( h ) \
|
||||
!AF_HINTS_TEST_SCALER( h, AF_SCALER_FLAG_NO_ADVANCE )
|
||||
|
||||
#define AF_HINTS_DO_BLUES( h ) ( !_af_debug_disable_blue_hints )
|
||||
|
||||
#else /* !AF_DEBUG */
|
||||
|
||||
#define AF_HINTS_DO_HORIZONTAL( h ) \
|
||||
!AF_HINTS_TEST_SCALER( h, AF_SCALER_FLAG_NO_HORIZONTAL )
|
||||
|
||||
@ -222,6 +241,10 @@ FT_BEGIN_HEADER
|
||||
#define AF_HINTS_DO_ADVANCE( h ) \
|
||||
!AF_HINTS_TEST_SCALER( h, AF_SCALER_FLAG_NO_ADVANCE )
|
||||
|
||||
#define AF_HINTS_DO_BLUES( h ) 1
|
||||
|
||||
#endif /* !AF_DEBUG */
|
||||
|
||||
|
||||
FT_LOCAL( AF_Direction )
|
||||
af_direction_compute( FT_Pos dx,
|
||||
|
@ -4,7 +4,7 @@
|
||||
/* */
|
||||
/* Auto-fitter hinting routines for latin script (body). */
|
||||
/* */
|
||||
/* Copyright 2003, 2004, 2005, 2006 by */
|
||||
/* Copyright 2003, 2004, 2005, 2006, 2007 by */
|
||||
/* David Turner, Robert Wilhelm, and Werner Lemberg. */
|
||||
/* */
|
||||
/* This file is part of the FreeType project, and may only be used, */
|
||||
@ -471,7 +471,7 @@
|
||||
if ( blue )
|
||||
{
|
||||
FT_Pos scaled = FT_MulFix( blue->shoot.org, scaler->y_scale );
|
||||
FT_Pos fitted = FT_PIX_ROUND( scaled );
|
||||
FT_Pos fitted = ( scaled + 40 ) & ~63;
|
||||
|
||||
|
||||
if ( scaled != fitted )
|
||||
@ -590,6 +590,7 @@
|
||||
FT_Memory memory = hints->memory;
|
||||
FT_Error error = AF_Err_Ok;
|
||||
AF_Segment segment = NULL;
|
||||
AF_SegmentRec seg0;
|
||||
AF_Point* contour = hints->contours;
|
||||
AF_Point* contour_limit = contour + hints->num_contours;
|
||||
AF_Direction major_dir, segment_dir;
|
||||
@ -601,6 +602,11 @@
|
||||
FT_Pos max_coord = -32000;
|
||||
#endif
|
||||
|
||||
|
||||
FT_ZERO( &seg0 );
|
||||
seg0.score = 32000;
|
||||
seg0.flags = AF_EDGE_NORMAL;
|
||||
|
||||
major_dir = (AF_Direction)FT_ABS( axis->major_dir );
|
||||
segment_dir = major_dir;
|
||||
|
||||
@ -717,6 +723,8 @@
|
||||
|
||||
segment->min_coord = (FT_Short)min_pos;
|
||||
segment->max_coord = (FT_Short)max_pos;
|
||||
segment->height = (FT_Short)( segment->max_coord -
|
||||
segment->min_coord );
|
||||
|
||||
on_edge = 0;
|
||||
segment = NULL;
|
||||
@ -742,15 +750,12 @@
|
||||
if ( error )
|
||||
goto Exit;
|
||||
|
||||
segment[0] = seg0;
|
||||
segment->dir = (FT_Char)segment_dir;
|
||||
segment->flags = AF_EDGE_NORMAL;
|
||||
min_pos = max_pos = point->u;
|
||||
segment->first = point;
|
||||
segment->last = point;
|
||||
segment->contour = contour;
|
||||
segment->score = 32000;
|
||||
segment->len = 0;
|
||||
segment->link = NULL;
|
||||
on_edge = 1;
|
||||
|
||||
#ifdef AF_HINT_METRICS
|
||||
@ -767,6 +772,58 @@
|
||||
|
||||
} /* contours */
|
||||
|
||||
|
||||
/* now slightly increase the height of segments when this makes */
|
||||
/* sense -- this is used to better detect and ignore serifs */
|
||||
{
|
||||
AF_Segment segments = axis->segments;
|
||||
AF_Segment segments_end = segments + axis->num_segments;
|
||||
|
||||
|
||||
for ( segment = segments; segment < segments_end; segment++ )
|
||||
{
|
||||
AF_Point first = segment->first;
|
||||
AF_Point last = segment->last;
|
||||
FT_Pos first_v = first->v;
|
||||
FT_Pos last_v = last->v;
|
||||
|
||||
|
||||
if ( first == last )
|
||||
continue;
|
||||
|
||||
if ( first_v < last_v )
|
||||
{
|
||||
AF_Point p;
|
||||
|
||||
|
||||
p = first->prev;
|
||||
if ( p->v < first_v )
|
||||
segment->height = (FT_Short)( segment->height +
|
||||
( ( first_v - p->v ) >> 1 ) );
|
||||
|
||||
p = last->next;
|
||||
if ( p->v > last_v )
|
||||
segment->height = (FT_Short)( segment->height +
|
||||
( ( p->v - last_v ) >> 1 ) );
|
||||
}
|
||||
else
|
||||
{
|
||||
AF_Point p;
|
||||
|
||||
|
||||
p = first->prev;
|
||||
if ( p->v > first_v )
|
||||
segment->height = (FT_Short)( segment->height +
|
||||
( ( p->v - first_v ) >> 1 ) );
|
||||
|
||||
p = last->next;
|
||||
if ( p->v < last_v )
|
||||
segment->height = (FT_Short)( segment->height +
|
||||
( ( last_v - p->v ) >> 1 ) );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef AF_HINT_METRICS
|
||||
/* we need to ensure that there are edges on the left-most and */
|
||||
/* right-most points of the glyph in order to hint the metrics; */
|
||||
@ -810,14 +867,11 @@
|
||||
if ( error )
|
||||
goto Exit;
|
||||
|
||||
segment[0] = seg0;
|
||||
segment->dir = segment_dir;
|
||||
segment->flags = AF_EDGE_NORMAL;
|
||||
segment->first = min_point;
|
||||
segment->last = min_point;
|
||||
segment->pos = min_pos;
|
||||
segment->score = 32000;
|
||||
segment->len = 0;
|
||||
segment->link = NULL;
|
||||
|
||||
segment = NULL;
|
||||
}
|
||||
@ -830,14 +884,11 @@
|
||||
if ( error )
|
||||
goto Exit;
|
||||
|
||||
segment[0] = seg0;
|
||||
segment->dir = segment_dir;
|
||||
segment->flags = AF_EDGE_NORMAL;
|
||||
segment->first = max_point;
|
||||
segment->last = max_point;
|
||||
segment->pos = max_pos;
|
||||
segment->score = 32000;
|
||||
segment->len = 0;
|
||||
segment->link = NULL;
|
||||
|
||||
segment = NULL;
|
||||
}
|
||||
@ -865,7 +916,7 @@
|
||||
if ( len_threshold == 0 )
|
||||
len_threshold = 1;
|
||||
|
||||
len_score = AF_LATIN_CONSTANT( hints->metrics, 3000 );
|
||||
len_score = AF_LATIN_CONSTANT( hints->metrics, 6000 );
|
||||
|
||||
/* now compare each segment to the others */
|
||||
for ( seg1 = segments; seg1 < segment_limit; seg1++ )
|
||||
@ -926,7 +977,6 @@
|
||||
|
||||
if ( seg2 )
|
||||
{
|
||||
seg2->num_linked++;
|
||||
if ( seg2->link != seg1 )
|
||||
{
|
||||
seg1->link = 0;
|
||||
@ -953,6 +1003,7 @@
|
||||
AF_Direction up_dir;
|
||||
FT_Fixed scale;
|
||||
FT_Pos edge_distance_threshold;
|
||||
FT_Pos segment_length_threshold;
|
||||
|
||||
|
||||
axis->num_edges = 0;
|
||||
@ -963,6 +1014,16 @@
|
||||
up_dir = ( dim == AF_DIMENSION_HORZ ) ? AF_DIR_UP
|
||||
: AF_DIR_RIGHT;
|
||||
|
||||
/*
|
||||
* We ignore all segments that are less than 1 pixels in length,
|
||||
* to avoid many problems with serif fonts. We compute the
|
||||
* corresponding threshold in font units.
|
||||
*/
|
||||
if ( dim == AF_DIMENSION_HORZ )
|
||||
segment_length_threshold = FT_DivFix( 96, hints->y_scale );
|
||||
else
|
||||
segment_length_threshold = 0;
|
||||
|
||||
/*********************************************************************/
|
||||
/* */
|
||||
/* We will begin by generating a sorted table of edges for the */
|
||||
@ -993,6 +1054,9 @@
|
||||
FT_Int ee;
|
||||
|
||||
|
||||
if ( seg->height < segment_length_threshold )
|
||||
continue;
|
||||
|
||||
/* look for an edge corresponding to the segment */
|
||||
for ( ee = 0; ee < axis->num_edges; ee++ )
|
||||
{
|
||||
@ -1110,9 +1174,11 @@
|
||||
|
||||
/* check for links -- if seg->serif is set, then seg->link must */
|
||||
/* be ignored */
|
||||
is_serif = (FT_Bool)( seg->serif && seg->serif->edge != edge );
|
||||
is_serif = (FT_Bool)( seg->serif &&
|
||||
seg->serif->edge &&
|
||||
seg->serif->edge != edge );
|
||||
|
||||
if ( seg->link || is_serif )
|
||||
if ( ( seg->link && seg->link->edge != NULL ) || is_serif )
|
||||
{
|
||||
AF_Edge edge2;
|
||||
AF_Segment seg2;
|
||||
@ -1524,6 +1590,8 @@
|
||||
else
|
||||
{
|
||||
/* strong hinting process: snap the stem width to integer pixels */
|
||||
FT_Pos org_dist = dist;
|
||||
|
||||
|
||||
dist = af_latin_snap_width( axis->widths, axis->width_count, dist );
|
||||
|
||||
@ -1559,7 +1627,28 @@
|
||||
dist = ( dist + 64 ) >> 1;
|
||||
|
||||
else if ( dist < 128 )
|
||||
{
|
||||
/* We only round to an integer width if the corresponding */
|
||||
/* distortion is less than 1/4 pixel. Otherwise this */
|
||||
/* makes everything worse since the diagonals, which are */
|
||||
/* not hinted, appear a lot bolder or thinner than the */
|
||||
/* vertical stems. */
|
||||
|
||||
FT_Int delta;
|
||||
|
||||
|
||||
dist = ( dist + 22 ) & ~63;
|
||||
delta = dist - org_dist;
|
||||
if ( delta < 0 )
|
||||
delta = -delta;
|
||||
|
||||
if (delta >= 16)
|
||||
{
|
||||
dist = org_dist;
|
||||
if ( dist < 48 )
|
||||
dist = ( dist + 64 ) >> 1;
|
||||
}
|
||||
}
|
||||
else
|
||||
/* round otherwise to prevent color fringes in LCD mode */
|
||||
dist = ( dist + 32 ) & ~63;
|
||||
@ -1592,6 +1681,11 @@
|
||||
|
||||
|
||||
stem_edge->pos = base_edge->pos + fitted_width;
|
||||
|
||||
AF_LOG(( "LINK: edge %d (opos=%.2f) linked to (%.2f), "
|
||||
"dist was %.2f, now %.2f\n",
|
||||
stem_edge-hints->axis[dim].edges, stem_edge->opos / 64.0,
|
||||
stem_edge->pos / 64.0, dist / 64.0, fitted_width / 64.0 ));
|
||||
}
|
||||
|
||||
|
||||
@ -1633,7 +1727,7 @@
|
||||
/* we begin by aligning all stems relative to the blue zone */
|
||||
/* if needed -- that's only for horizontal edges */
|
||||
|
||||
if ( dim == AF_DIMENSION_VERT )
|
||||
if ( dim == AF_DIMENSION_VERT && AF_HINTS_DO_BLUES( hints ) )
|
||||
{
|
||||
for ( edge = edges; edge < edge_limit; edge++ )
|
||||
{
|
||||
@ -1662,6 +1756,11 @@
|
||||
if ( !edge1 )
|
||||
continue;
|
||||
|
||||
AF_LOG(( "BLUE: edge %d (opos=%.2f) snapped to (%.2f), "
|
||||
"was (%.2f)\n",
|
||||
edge1-edges, edge1->opos / 64.0, blue->fit / 64.0,
|
||||
edge1->pos / 64.0 ));
|
||||
|
||||
edge1->pos = blue->fit;
|
||||
edge1->flags |= AF_EDGE_DONE;
|
||||
|
||||
@ -1697,8 +1796,10 @@
|
||||
/* now align the stem */
|
||||
|
||||
/* this should not happen, but it's better to be safe */
|
||||
if ( edge2->blue_edge || edge2 < edge )
|
||||
if ( edge2->blue_edge )
|
||||
{
|
||||
AF_LOG(( "ASSERTION FAILED for edge %d\n", edge2-edges ));
|
||||
|
||||
af_latin_align_linked_edge( hints, dim, edge2, edge );
|
||||
edge->flags |= AF_EDGE_DONE;
|
||||
continue;
|
||||
@ -1743,12 +1844,16 @@
|
||||
cur_pos1 += d_off;
|
||||
|
||||
edge->pos = cur_pos1 - cur_len / 2;
|
||||
edge2->pos = cur_pos1 + cur_len / 2;
|
||||
|
||||
edge2->pos = edge->pos + cur_len;
|
||||
}
|
||||
else
|
||||
edge->pos = FT_PIX_ROUND( edge->opos );
|
||||
|
||||
AF_LOG(( "ANCHOR: edge %d (opos=%.2f) and %d (opos=%.2f) "
|
||||
"snapped to (%.2f) (%.2f)\n",
|
||||
edge-edges, edge->opos / 64.0,
|
||||
edge2-edges, edge2->opos / 64.0,
|
||||
edge->pos / 64.0, edge2->pos / 64.0 ));
|
||||
anchor = edge;
|
||||
|
||||
edge->flags |= AF_EDGE_DONE;
|
||||
@ -1770,7 +1875,10 @@
|
||||
(AF_Edge_Flags)edge->flags,
|
||||
(AF_Edge_Flags)edge2->flags );
|
||||
|
||||
if ( cur_len < 96 )
|
||||
if ( edge2->flags & AF_EDGE_DONE )
|
||||
edge->pos = edge2->pos - cur_len;
|
||||
|
||||
else if ( cur_len < 96 )
|
||||
{
|
||||
FT_Pos u_off, d_off;
|
||||
|
||||
@ -1800,6 +1908,12 @@
|
||||
|
||||
edge->pos = cur_pos1 - cur_len / 2;
|
||||
edge2->pos = cur_pos1 + cur_len / 2;
|
||||
|
||||
AF_LOG(( "STEM: %d (opos=%.2f) to %d (opos=%.2f) "
|
||||
"snapped to (%.2f) and (%.2f)\n",
|
||||
edge-edges, edge->opos / 64.0,
|
||||
edge2-edges, edge2->opos / 64.0,
|
||||
edge->pos / 64.0, edge2->pos / 64.0 ));
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -1824,13 +1938,23 @@
|
||||
|
||||
edge->pos = ( delta1 < delta2 ) ? cur_pos1 : cur_pos2;
|
||||
edge2->pos = edge->pos + cur_len;
|
||||
|
||||
AF_LOG(( "STEM: %d (opos=%.2f) to %d (opos=%.2f) "
|
||||
"snapped to (%.2f) and (%.2f)\n",
|
||||
edge-edges, edge->opos / 64.0,
|
||||
edge2-edges, edge2->opos / 64.0,
|
||||
edge->pos / 64.0, edge2->pos / 64.0 ));
|
||||
}
|
||||
|
||||
edge->flags |= AF_EDGE_DONE;
|
||||
edge2->flags |= AF_EDGE_DONE;
|
||||
|
||||
if ( edge > edges && edge->pos < edge[-1].pos )
|
||||
{
|
||||
AF_LOG(( "BOUND: %d (pos=%.2f) to (%.2f)\n",
|
||||
edge-edges, edge->pos / 64.0, edge[-1].pos / 64.0 ));
|
||||
edge->pos = edge[-1].pos;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -1904,19 +2028,63 @@
|
||||
*/
|
||||
for ( edge = edges; edge < edge_limit; edge++ )
|
||||
{
|
||||
FT_Pos delta;
|
||||
|
||||
|
||||
if ( edge->flags & AF_EDGE_DONE )
|
||||
continue;
|
||||
|
||||
delta = 1000;
|
||||
|
||||
if ( edge->serif )
|
||||
{
|
||||
delta = edge->serif->opos - edge->opos;
|
||||
if ( delta < 0 )
|
||||
delta = -delta;
|
||||
}
|
||||
|
||||
if ( delta < 64 + 16 )
|
||||
{
|
||||
af_latin_align_serif_edge( hints, edge->serif, edge );
|
||||
AF_LOG(( "SERIF: edge %d (opos=%.2f) serif to %d (opos=%.2f) "
|
||||
"aligned to (%.2f)\n",
|
||||
edge-edges, edge->opos / 64.0,
|
||||
edge->serif - edges, edge->serif->opos / 64.0,
|
||||
edge->pos / 64.0 ));
|
||||
}
|
||||
else if ( !anchor )
|
||||
{
|
||||
AF_LOG(( "SERIF_ANCHOR: edge %d (opos=%.2f) snapped to (%.2f)\n",
|
||||
edge-edges, edge->opos / 64.0, edge->pos / 64.0 ));
|
||||
edge->pos = FT_PIX_ROUND( edge->opos );
|
||||
anchor = edge;
|
||||
}
|
||||
else
|
||||
edge->pos = anchor->pos +
|
||||
FT_PIX_ROUND( edge->opos - anchor->opos );
|
||||
{
|
||||
AF_Edge before, after;
|
||||
|
||||
|
||||
for ( before = edge - 1; before >= edges; before-- )
|
||||
if ( before->flags & AF_EDGE_DONE )
|
||||
break;
|
||||
|
||||
for ( after = edge + 1; after < edge_limit; after++ )
|
||||
if ( after->flags & AF_EDGE_DONE )
|
||||
break;
|
||||
|
||||
if ( before >= edges && before < edge &&
|
||||
after < edge_limit && after > edge )
|
||||
edge->pos = before->pos +
|
||||
FT_MulDiv( edge->opos - before->opos,
|
||||
after->pos - before->pos,
|
||||
after->opos - before->opos );
|
||||
else
|
||||
edge->pos = anchor->pos +
|
||||
FT_PIX_ROUND( edge->opos - anchor->opos );
|
||||
|
||||
AF_LOG(( "SERIF_LINK: edge %d (opos=%.2f) snapped to (%.2f)\n",
|
||||
edge-edges, edge->opos / 64.0, edge->pos / 64.0 ));
|
||||
}
|
||||
|
||||
edge->flags |= AF_EDGE_DONE;
|
||||
|
||||
|
@ -30,7 +30,9 @@
|
||||
FT_ZERO( loader );
|
||||
|
||||
af_glyph_hints_init( &loader->hints, memory );
|
||||
|
||||
#ifdef AF_DEBUG
|
||||
_af_debug_hints = &loader->hints;
|
||||
#endif
|
||||
return FT_GlyphLoader_New( memory, &loader->gloader );
|
||||
}
|
||||
|
||||
@ -71,6 +73,9 @@
|
||||
loader->face = NULL;
|
||||
loader->globals = NULL;
|
||||
|
||||
#ifdef AF_DEBUG
|
||||
_af_debug_hints = NULL;
|
||||
#endif
|
||||
FT_GlyphLoader_Done( loader->gloader );
|
||||
loader->gloader = NULL;
|
||||
}
|
||||
@ -201,6 +206,12 @@
|
||||
loader->pp1.x = FT_PIX_ROUND( pp1x_uh );
|
||||
loader->pp2.x = FT_PIX_ROUND( pp2x_uh );
|
||||
|
||||
if ( loader->pp1.x >= new_lsb )
|
||||
loader->pp1.x -= 64;
|
||||
|
||||
if ( loader->pp2.x <= pp2x_uh )
|
||||
loader->pp2.x += 64;
|
||||
|
||||
slot->lsb_delta = loader->pp1.x - pp1x_uh;
|
||||
slot->rsb_delta = loader->pp2.x - pp2x_uh;
|
||||
}
|
||||
|
@ -4,7 +4,7 @@
|
||||
/* */
|
||||
/* Auto-fitter module implementation (body). */
|
||||
/* */
|
||||
/* Copyright 2003, 2004, 2005 by */
|
||||
/* Copyright 2003, 2004, 2005, 2006 by */
|
||||
/* David Turner, Robert Wilhelm, and Werner Lemberg. */
|
||||
/* */
|
||||
/* This file is part of the FreeType project, and may only be used, */
|
||||
@ -19,6 +19,14 @@
|
||||
#include "afmodule.h"
|
||||
#include "afloader.h"
|
||||
|
||||
#ifdef AF_DEBUG
|
||||
int _af_debug;
|
||||
int _af_debug_disable_horz_hints;
|
||||
int _af_debug_disable_vert_hints;
|
||||
int _af_debug_disable_blue_hints;
|
||||
void* _af_debug_hints;
|
||||
#endif
|
||||
|
||||
#include FT_INTERNAL_OBJECTS_H
|
||||
|
||||
|
||||
|
@ -4,7 +4,7 @@
|
||||
/* */
|
||||
/* Auto-fitter types (specification only). */
|
||||
/* */
|
||||
/* Copyright 2003, 2004, 2005, 2006 by */
|
||||
/* Copyright 2003, 2004, 2005, 2006, 2007 by */
|
||||
/* David Turner, Robert Wilhelm, and Werner Lemberg. */
|
||||
/* */
|
||||
/* This file is part of the FreeType project, and may only be used, */
|
||||
@ -59,14 +59,19 @@ FT_BEGIN_HEADER
|
||||
#ifdef AF_DEBUG
|
||||
|
||||
#include <stdio.h>
|
||||
#define AF_LOG( x ) do { if ( _af_debug ) printf x; } while ( 0 )
|
||||
|
||||
#define AF_LOG( x ) printf x
|
||||
extern int _af_debug;
|
||||
extern int _af_debug_disable_horz_hints;
|
||||
extern int _af_debug_disable_vert_hints;
|
||||
extern int _af_debug_disable_blue_hints;
|
||||
extern void* _af_debug_hints;
|
||||
|
||||
#else
|
||||
#else /* !AF_DEBUG */
|
||||
|
||||
#define AF_LOG( x ) do ; while ( 0 ) /* nothing */
|
||||
|
||||
#endif /* AF_DEBUG */
|
||||
#endif /* !AF_DEBUG */
|
||||
|
||||
|
||||
/*************************************************************************/
|
||||
@ -118,6 +123,7 @@ FT_BEGIN_HEADER
|
||||
#define AF_ANGLE_PI4 ( AF_ANGLE_PI / 4 )
|
||||
|
||||
|
||||
#if 0
|
||||
/*
|
||||
* compute the angle of a given 2-D vector
|
||||
*/
|
||||
@ -126,7 +132,6 @@ FT_BEGIN_HEADER
|
||||
FT_Pos dy );
|
||||
|
||||
|
||||
#if 0
|
||||
/*
|
||||
* compute `angle2 - angle1'; the result is always within
|
||||
* the range [-AF_ANGLE_PI .. AF_ANGLE_PI - 1]
|
||||
|
@ -38,7 +38,7 @@ UseFreeTypeHeaders ;
|
||||
local _sources = system init glyph mm bdf
|
||||
bbox debug xf86 type1 pfr
|
||||
stroke winfnt otval bitmap synth
|
||||
gxval
|
||||
gxval lcdfil gasp
|
||||
;
|
||||
|
||||
FT2_Library $(FT2_LIB) : ft$(_sources).c ;
|
||||
|
@ -49,7 +49,7 @@
|
||||
FT_UNUSED( library );
|
||||
|
||||
FT_Stream_OpenMemory( stream, base, size );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
FT_BASE_DEF( FT_Error )
|
||||
@ -57,7 +57,7 @@
|
||||
FT_ULong pos )
|
||||
{
|
||||
return FT_Stream_Seek( stream, pos );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
FT_BASE_DEF( FT_Error )
|
||||
@ -65,7 +65,7 @@
|
||||
FT_Long distance )
|
||||
{
|
||||
return FT_Stream_Skip( stream, distance );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
FT_BASE_DEF( FT_Error )
|
||||
@ -74,7 +74,7 @@
|
||||
FT_ULong count )
|
||||
{
|
||||
return FT_Stream_Read( stream, buffer, count );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
FT_BASE_DEF( FT_Error )
|
||||
@ -84,7 +84,7 @@
|
||||
FT_ULong count )
|
||||
{
|
||||
return FT_Stream_ReadAt( stream, pos, buffer, count );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
FT_BASE_DEF( FT_Error )
|
||||
@ -93,7 +93,7 @@
|
||||
FT_Byte** pbytes )
|
||||
{
|
||||
return FT_Stream_ExtractFrame( stream, count, pbytes );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
FT_BASE_DEF( void )
|
||||
@ -101,14 +101,14 @@
|
||||
FT_Byte** pbytes )
|
||||
{
|
||||
FT_Stream_ReleaseFrame( stream, pbytes );
|
||||
}
|
||||
}
|
||||
|
||||
FT_BASE_DEF( FT_Error )
|
||||
FT_Access_Frame( FT_Stream stream,
|
||||
FT_ULong count )
|
||||
{
|
||||
return FT_Stream_EnterFrame( stream, count );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
FT_BASE_DEF( void )
|
||||
@ -116,6 +116,6 @@
|
||||
{
|
||||
FT_Stream_ExitFrame( stream );
|
||||
}
|
||||
|
||||
|
||||
|
||||
/* END */
|
||||
|
@ -4,7 +4,7 @@
|
||||
/* */
|
||||
/* Single object library component (body only). */
|
||||
/* */
|
||||
/* Copyright 1996-2001, 2002, 2003, 2004 by */
|
||||
/* Copyright 1996-2001, 2002, 2003, 2004, 2006 by */
|
||||
/* David Turner, Robert Wilhelm, and Werner Lemberg. */
|
||||
/* */
|
||||
/* This file is part of the FreeType project, and may only be used, */
|
||||
@ -20,16 +20,16 @@
|
||||
|
||||
#define FT_MAKE_OPTION_SINGLE_OBJECT
|
||||
|
||||
#include "ftutil.c"
|
||||
#include "ftdbgmem.c"
|
||||
#include "ftstream.c"
|
||||
#include "ftcalc.c"
|
||||
#include "fttrigon.c"
|
||||
#include "ftoutln.c"
|
||||
#include "ftdbgmem.c"
|
||||
#include "ftgloadr.c"
|
||||
#include "ftobjs.c"
|
||||
#include "ftnames.c"
|
||||
#include "ftobjs.c"
|
||||
#include "ftoutln.c"
|
||||
#include "ftrfork.c"
|
||||
#include "ftstream.c"
|
||||
#include "fttrigon.c"
|
||||
#include "ftutil.c"
|
||||
|
||||
#if defined( __APPLE__ ) && !defined ( DARWIN_NO_CARBON )
|
||||
#include "ftmac.c"
|
||||
|
@ -5,7 +5,7 @@
|
||||
/* FreeType utility functions for converting 1bpp, 2bpp, 4bpp, and 8bpp */
|
||||
/* bitmaps into 8bpp format (body). */
|
||||
/* */
|
||||
/* Copyright 2004, 2005, 2006 by */
|
||||
/* Copyright 2004, 2005, 2006, 2007 by */
|
||||
/* David Turner, Robert Wilhelm, and Werner Lemberg. */
|
||||
/* */
|
||||
/* This file is part of the FreeType project, and may only be used, */
|
||||
@ -104,10 +104,11 @@
|
||||
int pitch;
|
||||
int new_pitch;
|
||||
FT_UInt ppb;
|
||||
FT_Int i;
|
||||
FT_Int i, width;
|
||||
unsigned char* buffer;
|
||||
|
||||
|
||||
width = bitmap->width;
|
||||
pitch = bitmap->pitch;
|
||||
if ( pitch < 0 )
|
||||
pitch = -pitch;
|
||||
@ -170,15 +171,21 @@
|
||||
|
||||
if ( bitmap->pitch > 0 )
|
||||
{
|
||||
FT_Int len = ( width + ppb - 1 ) / ppb;
|
||||
|
||||
|
||||
for ( i = 0; i < bitmap->rows; i++ )
|
||||
FT_MEM_COPY( buffer + new_pitch * ( ypixels + i ),
|
||||
bitmap->buffer + pitch * i, pitch );
|
||||
bitmap->buffer + pitch * i, len );
|
||||
}
|
||||
else
|
||||
{
|
||||
FT_Int len = ( width + ppb - 1 ) / ppb;
|
||||
|
||||
|
||||
for ( i = 0; i < bitmap->rows; i++ )
|
||||
FT_MEM_COPY( buffer + new_pitch * i,
|
||||
bitmap->buffer + pitch * i, pitch );
|
||||
bitmap->buffer + pitch * i, len );
|
||||
}
|
||||
|
||||
FT_FREE( bitmap->buffer );
|
||||
|
@ -159,7 +159,7 @@
|
||||
}
|
||||
|
||||
|
||||
#ifdef TT_CONFIG_OPTION_BYTECODE_INTERPRETER
|
||||
#ifdef TT_USE_BYTECODE_INTERPRETER
|
||||
|
||||
/* documentation is in ftcalc.h */
|
||||
|
||||
@ -183,7 +183,7 @@
|
||||
return ( s > 0 ) ? d : -d;
|
||||
}
|
||||
|
||||
#endif /* TT_CONFIG_OPTION_BYTECODE_INTERPRETER */
|
||||
#endif /* TT_USE_BYTECODE_INTERPRETER */
|
||||
|
||||
|
||||
/* documentation is in freetype.h */
|
||||
@ -228,7 +228,7 @@
|
||||
}
|
||||
|
||||
|
||||
#else /* FT_LONG64 */
|
||||
#else /* !FT_LONG64 */
|
||||
|
||||
|
||||
static void
|
||||
@ -302,12 +302,11 @@
|
||||
FT_Int64* y,
|
||||
FT_Int64 *z )
|
||||
{
|
||||
register FT_UInt32 lo, hi, max;
|
||||
register FT_UInt32 lo, hi;
|
||||
|
||||
|
||||
max = x->lo > y->lo ? x->lo : y->lo;
|
||||
lo = x->lo + y->lo;
|
||||
hi = x->hi + y->hi + ( lo < max );
|
||||
lo = x->lo + y->lo;
|
||||
hi = x->hi + y->hi + ( lo < x->lo );
|
||||
|
||||
z->lo = lo;
|
||||
z->hi = hi;
|
||||
@ -316,6 +315,23 @@
|
||||
|
||||
/* documentation is in freetype.h */
|
||||
|
||||
/* The FT_MulDiv function has been optimized thanks to ideas from */
|
||||
/* Graham Asher. The trick is to optimize computation when everything */
|
||||
/* fits within 32-bits (a rather common case). */
|
||||
/* */
|
||||
/* we compute 'a*b+c/2', then divide it by 'c'. (positive values) */
|
||||
/* */
|
||||
/* 46340 is FLOOR(SQRT(2^31-1)). */
|
||||
/* */
|
||||
/* if ( a <= 46340 && b <= 46340 ) then ( a*b <= 0x7FFEA810 ) */
|
||||
/* */
|
||||
/* 0x7FFFFFFF - 0x7FFEA810 = 0x157F0 */
|
||||
/* */
|
||||
/* if ( c < 0x157F0*2 ) then ( a*b+c/2 <= 0x7FFFFFFF ) */
|
||||
/* */
|
||||
/* and 2*0x157F0 = 176096 */
|
||||
/* */
|
||||
|
||||
FT_EXPORT_DEF( FT_Long )
|
||||
FT_MulDiv( FT_Long a,
|
||||
FT_Long b,
|
||||
@ -353,7 +369,7 @@
|
||||
}
|
||||
|
||||
|
||||
#ifdef TT_CONFIG_OPTION_BYTECODE_INTERPRETER
|
||||
#ifdef TT_USE_BYTECODE_INTERPRETER
|
||||
|
||||
FT_BASE_DEF( FT_Long )
|
||||
FT_MulDiv_No_Round( FT_Long a,
|
||||
@ -387,7 +403,7 @@
|
||||
return ( s < 0 ? -a : a );
|
||||
}
|
||||
|
||||
#endif /* TT_CONFIG_OPTION_BYTECODE_INTERPRETER */
|
||||
#endif /* TT_USE_BYTECODE_INTERPRETER */
|
||||
|
||||
|
||||
/* documentation is in freetype.h */
|
||||
@ -396,7 +412,32 @@
|
||||
FT_MulFix( FT_Long a,
|
||||
FT_Long b )
|
||||
{
|
||||
#if 1
|
||||
/* use inline assembly to speed up things a bit */
|
||||
|
||||
#if defined( __GNUC__ ) && defined( i386 )
|
||||
|
||||
FT_Long result;
|
||||
|
||||
|
||||
__asm__ __volatile__ (
|
||||
"imul %%edx\n"
|
||||
"movl %%edx, %%ecx\n"
|
||||
"sarl $31, %%ecx\n"
|
||||
"addl $0x8000, %%ecx\n"
|
||||
"addl %%ecx, %%eax\n"
|
||||
"adcl $0, %%edx\n"
|
||||
"shrl $16, %%eax\n"
|
||||
"shll $16, %%edx\n"
|
||||
"addl %%edx, %%eax\n"
|
||||
"mov %%eax, %0\n"
|
||||
: "=r"(result)
|
||||
: "a"(a), "d"(b)
|
||||
: "%ecx"
|
||||
);
|
||||
return result;
|
||||
|
||||
#elif 1
|
||||
|
||||
FT_Long sa, sb;
|
||||
FT_ULong ua, ub;
|
||||
|
||||
@ -405,24 +446,22 @@
|
||||
return a;
|
||||
|
||||
sa = ( a >> ( sizeof ( a ) * 8 - 1 ) );
|
||||
a = ( a ^ sa ) - sa;
|
||||
a = ( a ^ sa ) - sa;
|
||||
sb = ( b >> ( sizeof ( b ) * 8 - 1 ) );
|
||||
b = ( b ^ sb ) - sb;
|
||||
b = ( b ^ sb ) - sb;
|
||||
|
||||
ua = (FT_ULong)a;
|
||||
ub = (FT_ULong)b;
|
||||
|
||||
if ( ua <= 2048 && ub <= 1048576L )
|
||||
{
|
||||
ua = ( ua * ub + 0x8000 ) >> 16;
|
||||
}
|
||||
ua = ( ua * ub + 0x8000U ) >> 16;
|
||||
else
|
||||
{
|
||||
FT_ULong al = ua & 0xFFFF;
|
||||
FT_ULong al = ua & 0xFFFFU;
|
||||
|
||||
|
||||
ua = ( ua >> 16 ) * ub + al * ( ub >> 16 ) +
|
||||
( ( al * ( ub & 0xFFFF ) + 0x8000 ) >> 16 );
|
||||
( ( al * ( ub & 0xFFFFU ) + 0x8000U ) >> 16 );
|
||||
}
|
||||
|
||||
sa ^= sb,
|
||||
@ -439,23 +478,21 @@
|
||||
if ( a == 0 || b == 0x10000L )
|
||||
return a;
|
||||
|
||||
s = a; a = FT_ABS(a);
|
||||
s ^= b; b = FT_ABS(b);
|
||||
s = a; a = FT_ABS( a );
|
||||
s ^= b; b = FT_ABS( b );
|
||||
|
||||
ua = (FT_ULong)a;
|
||||
ub = (FT_ULong)b;
|
||||
|
||||
if ( ua <= 2048 && ub <= 1048576L )
|
||||
{
|
||||
ua = ( ua * ub + 0x8000L ) >> 16;
|
||||
}
|
||||
ua = ( ua * ub + 0x8000UL ) >> 16;
|
||||
else
|
||||
{
|
||||
FT_ULong al = ua & 0xFFFFL;
|
||||
FT_ULong al = ua & 0xFFFFUL;
|
||||
|
||||
|
||||
ua = ( ua >> 16 ) * ub + al * ( ub >> 16 ) +
|
||||
( ( al * ( ub & 0xFFFFL ) + 0x8000L ) >> 16 );
|
||||
( ( al * ( ub & 0xFFFFUL ) + 0x8000UL ) >> 16 );
|
||||
}
|
||||
|
||||
return ( s < 0 ? -(FT_Long)ua : (FT_Long)ua );
|
||||
@ -531,7 +568,7 @@
|
||||
|
||||
|
||||
/* apparently, the second version of this code is not compiled correctly */
|
||||
/* on Mac machines with the MPW C compiler.. tsk, tsk, tsk... */
|
||||
/* on Mac machines with the MPW C compiler.. tsk, tsk, tsk... */
|
||||
|
||||
#if 1
|
||||
|
||||
@ -568,7 +605,7 @@
|
||||
if ( r >= (FT_UInt32)y ) /* we know y is to be treated as unsigned here */
|
||||
return ( s < 0 ? 0x80000001UL : 0x7FFFFFFFUL );
|
||||
/* Return Max/Min Int32 if division overflow. */
|
||||
/* This includes division by zero! */
|
||||
/* This includes division by zero! */
|
||||
q = 0;
|
||||
for ( i = 0; i < 32; i++ )
|
||||
{
|
||||
@ -664,4 +701,123 @@
|
||||
}
|
||||
|
||||
|
||||
/* documentation is in ftcalc.h */
|
||||
|
||||
FT_BASE_DEF( FT_Int )
|
||||
ft_corner_orientation( FT_Pos in_x,
|
||||
FT_Pos in_y,
|
||||
FT_Pos out_x,
|
||||
FT_Pos out_y )
|
||||
{
|
||||
FT_Int result;
|
||||
|
||||
|
||||
/* deal with the trivial cases quickly */
|
||||
if ( in_y == 0 )
|
||||
{
|
||||
if ( in_x >= 0 )
|
||||
result = out_y;
|
||||
else
|
||||
result = -out_y;
|
||||
}
|
||||
else if ( in_x == 0 )
|
||||
{
|
||||
if ( in_y >= 0 )
|
||||
result = -out_x;
|
||||
else
|
||||
result = out_x;
|
||||
}
|
||||
else if ( out_y == 0 )
|
||||
{
|
||||
if ( out_x >= 0 )
|
||||
result = in_y;
|
||||
else
|
||||
result = -in_y;
|
||||
}
|
||||
else if ( out_x == 0 )
|
||||
{
|
||||
if ( out_y >= 0 )
|
||||
result = -in_x;
|
||||
else
|
||||
result = in_x;
|
||||
}
|
||||
else /* general case */
|
||||
{
|
||||
|
||||
#ifdef FT_LONG64
|
||||
|
||||
FT_Int64 delta = (FT_Int64)in_x * out_y - (FT_Int64)in_y * out_x;
|
||||
|
||||
|
||||
if ( delta == 0 )
|
||||
result = 0;
|
||||
else
|
||||
result = 1 - 2 * ( delta < 0 );
|
||||
|
||||
#else
|
||||
|
||||
FT_Int64 z1, z2;
|
||||
|
||||
|
||||
ft_multo64( in_x, out_y, &z1 );
|
||||
ft_multo64( in_y, out_x, &z2 );
|
||||
|
||||
if ( z1.hi > z2.hi )
|
||||
result = +1;
|
||||
else if ( z1.hi < z2.hi )
|
||||
result = -1;
|
||||
else if ( z1.lo > z2.lo )
|
||||
result = +1;
|
||||
else if ( z1.lo < z2.lo )
|
||||
result = -1;
|
||||
else
|
||||
result = 0;
|
||||
|
||||
#endif
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
/* documentation is in ftcalc.h */
|
||||
|
||||
FT_BASE_DEF( FT_Int )
|
||||
ft_corner_is_flat( FT_Pos in_x,
|
||||
FT_Pos in_y,
|
||||
FT_Pos out_x,
|
||||
FT_Pos out_y )
|
||||
{
|
||||
FT_Pos ax = in_x;
|
||||
FT_Pos ay = in_y;
|
||||
|
||||
FT_Pos d_in, d_out, d_corner;
|
||||
|
||||
|
||||
if ( ax < 0 )
|
||||
ax = -ax;
|
||||
if ( ay < 0 )
|
||||
ay = -ay;
|
||||
d_in = ax + ay;
|
||||
|
||||
ax = out_x;
|
||||
if ( ax < 0 )
|
||||
ax = -ax;
|
||||
ay = out_y;
|
||||
if ( ay < 0 )
|
||||
ay = -ay;
|
||||
d_out = ax + ay;
|
||||
|
||||
ax = out_x + in_x;
|
||||
if ( ax < 0 )
|
||||
ax = -ax;
|
||||
ay = out_y + in_y;
|
||||
if ( ay < 0 )
|
||||
ay = -ay;
|
||||
d_corner = ax + ay;
|
||||
|
||||
return ( d_in + d_out - d_corner ) < ( d_corner >> 4 );
|
||||
}
|
||||
|
||||
|
||||
/* END */
|
||||
|
@ -460,7 +460,9 @@
|
||||
FT_MemSource node, *pnode;
|
||||
|
||||
|
||||
hash = (FT_UInt32)(void*)_ft_debug_file +
|
||||
/* cast to FT_PtrDist first since void* can be larger */
|
||||
/* than FT_UInt32 and GCC 4.1.1 emits a warning */
|
||||
hash = (FT_UInt32)(FT_PtrDist)(void*)_ft_debug_file +
|
||||
(FT_UInt32)( 5 * _ft_debug_lineno );
|
||||
pnode = &table->sources[hash % FT_MEM_SOURCE_BUCKETS];
|
||||
|
||||
|
61
src/libs/freetype2/base/ftgasp.c
Normal file
61
src/libs/freetype2/base/ftgasp.c
Normal file
@ -0,0 +1,61 @@
|
||||
/***************************************************************************/
|
||||
/* */
|
||||
/* ftgasp.c */
|
||||
/* */
|
||||
/* Access of TrueType's `gasp' table (body). */
|
||||
/* */
|
||||
/* Copyright 2007 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_GASP_H
|
||||
#include FT_INTERNAL_TRUETYPE_TYPES_H
|
||||
|
||||
|
||||
FT_EXPORT_DEF( FT_Int )
|
||||
FT_Get_Gasp( FT_Face face,
|
||||
FT_UInt ppem )
|
||||
{
|
||||
FT_Int result = FT_GASP_NO_TABLE;
|
||||
|
||||
|
||||
if ( face && FT_IS_SFNT( face ) )
|
||||
{
|
||||
TT_Face ttface = (TT_Face)face;
|
||||
|
||||
|
||||
if ( ttface->gasp.numRanges > 0 )
|
||||
{
|
||||
TT_GaspRange range = ttface->gasp.gaspRanges;
|
||||
TT_GaspRange range_end = range + ttface->gasp.numRanges;
|
||||
|
||||
|
||||
while ( ppem > range->maxPPEM )
|
||||
{
|
||||
range++;
|
||||
if ( range >= range_end )
|
||||
goto Exit;
|
||||
}
|
||||
|
||||
result = range->gaspFlag;
|
||||
|
||||
/* ensure that we don't have spurious bits */
|
||||
if ( ttface->gasp.version == 0 )
|
||||
result &= 3;
|
||||
}
|
||||
}
|
||||
Exit:
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
/* END */
|
@ -4,7 +4,7 @@
|
||||
/* */
|
||||
/* The FreeType glyph loader (body). */
|
||||
/* */
|
||||
/* Copyright 2002, 2003, 2004, 2005 by */
|
||||
/* Copyright 2002, 2003, 2004, 2005, 2006 by */
|
||||
/* David Turner, Robert Wilhelm, and Werner Lemberg */
|
||||
/* */
|
||||
/* This file is part of the FreeType project, and may only be used, */
|
||||
@ -112,6 +112,8 @@
|
||||
FT_FREE( loader->base.extra_points );
|
||||
FT_FREE( loader->base.subglyphs );
|
||||
|
||||
loader->base.extra_points2 = NULL;
|
||||
|
||||
loader->max_points = 0;
|
||||
loader->max_contours = 0;
|
||||
loader->max_subglyphs = 0;
|
||||
@ -149,8 +151,13 @@
|
||||
|
||||
/* handle extra points table - if any */
|
||||
if ( loader->use_extra )
|
||||
loader->current.extra_points =
|
||||
loader->base.extra_points + base->n_points;
|
||||
{
|
||||
loader->current.extra_points = loader->base.extra_points +
|
||||
base->n_points;
|
||||
|
||||
loader->current.extra_points2 = loader->base.extra_points2 +
|
||||
base->n_points;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -161,9 +168,12 @@
|
||||
FT_Memory memory = loader->memory;
|
||||
|
||||
|
||||
if ( !FT_NEW_ARRAY( loader->base.extra_points, loader->max_points ) )
|
||||
if ( !FT_NEW_ARRAY( loader->base.extra_points, 2 * loader->max_points ) )
|
||||
{
|
||||
loader->use_extra = 1;
|
||||
loader->use_extra = 1;
|
||||
loader->base.extra_points2 = loader->base.extra_points +
|
||||
loader->max_points;
|
||||
|
||||
FT_GlyphLoader_Adjust_Points( loader );
|
||||
}
|
||||
return error;
|
||||
@ -212,9 +222,18 @@
|
||||
FT_RENEW_ARRAY( base->tags, old_max, new_max ) )
|
||||
goto Exit;
|
||||
|
||||
if ( loader->use_extra &&
|
||||
FT_RENEW_ARRAY( loader->base.extra_points, old_max, new_max ) )
|
||||
goto Exit;
|
||||
if ( loader->use_extra )
|
||||
{
|
||||
if ( FT_RENEW_ARRAY( loader->base.extra_points,
|
||||
old_max * 2, new_max * 2 ) )
|
||||
goto Exit;
|
||||
|
||||
FT_ARRAY_MOVE( loader->base.extra_points + new_max,
|
||||
loader->base.extra_points + old_max,
|
||||
old_max );
|
||||
|
||||
loader->base.extra_points2 = loader->base.extra_points + new_max;
|
||||
}
|
||||
|
||||
adjust = 1;
|
||||
loader->max_points = new_max;
|
||||
@ -355,8 +374,12 @@
|
||||
|
||||
/* do we need to copy the extra points? */
|
||||
if ( target->use_extra && source->use_extra )
|
||||
{
|
||||
FT_ARRAY_COPY( target->base.extra_points, source->base.extra_points,
|
||||
num_points );
|
||||
FT_ARRAY_COPY( target->base.extra_points2, source->base.extra_points2,
|
||||
num_points );
|
||||
}
|
||||
|
||||
out->n_points = (short)num_points;
|
||||
out->n_contours = (short)num_contours;
|
||||
|
@ -4,7 +4,7 @@
|
||||
/* */
|
||||
/* FreeType API for validating TrueTyepGX/AAT tables (body). */
|
||||
/* */
|
||||
/* Copyright 2004, 2005 by */
|
||||
/* Copyright 2004, 2005, 2006 by */
|
||||
/* Masatake YAMATO, Redhat K.K, */
|
||||
/* David Turner, Robert Wilhelm, and Werner Lemberg. */
|
||||
/* */
|
||||
@ -62,7 +62,7 @@
|
||||
tables,
|
||||
table_length );
|
||||
else
|
||||
error = FT_Err_Invalid_Argument;
|
||||
error = FT_Err_Unimplemented_Feature;
|
||||
|
||||
Exit:
|
||||
return error;
|
||||
@ -108,7 +108,7 @@
|
||||
validation_flags,
|
||||
ckern_table );
|
||||
else
|
||||
error = FT_Err_Invalid_Argument;
|
||||
error = FT_Err_Unimplemented_Feature;
|
||||
|
||||
Exit:
|
||||
return error;
|
||||
|
351
src/libs/freetype2/base/ftlcdfil.c
Normal file
351
src/libs/freetype2/base/ftlcdfil.c
Normal file
@ -0,0 +1,351 @@
|
||||
/***************************************************************************/
|
||||
/* */
|
||||
/* ftlcdfil.c */
|
||||
/* */
|
||||
/* FreeType API for color filtering of subpixel bitmap glyphs (body). */
|
||||
/* */
|
||||
/* Copyright 2006 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_LCD_FILTER_H
|
||||
#include FT_IMAGE_H
|
||||
#include FT_INTERNAL_OBJECTS_H
|
||||
|
||||
|
||||
#ifdef FT_CONFIG_OPTION_SUBPIXEL_RENDERING
|
||||
|
||||
/* define USE_LEGACY to implement the legacy filter */
|
||||
#define USE_LEGACY
|
||||
|
||||
/* FIR filter used by the default and light filters */
|
||||
static void
|
||||
_ft_lcd_filter_fir( FT_Bitmap* bitmap,
|
||||
FT_Render_Mode mode,
|
||||
FT_Library library )
|
||||
{
|
||||
FT_Byte* weights = library->lcd_weights;
|
||||
FT_UInt width = (FT_UInt)bitmap->width;
|
||||
FT_UInt height = (FT_UInt)bitmap->rows;
|
||||
|
||||
|
||||
/* horizontal in-place FIR filter */
|
||||
if ( mode == FT_RENDER_MODE_LCD && width >= 4 )
|
||||
{
|
||||
FT_Byte* line = bitmap->buffer;
|
||||
|
||||
|
||||
for ( ; height > 0; height--, line += bitmap->pitch )
|
||||
{
|
||||
FT_UInt fir[5];
|
||||
FT_UInt val1, xx;
|
||||
|
||||
|
||||
val1 = line[0];
|
||||
fir[0] = weights[2] * val1;
|
||||
fir[1] = weights[3] * val1;
|
||||
fir[2] = weights[4] * val1;
|
||||
fir[3] = 0;
|
||||
fir[4] = 0;
|
||||
|
||||
val1 = line[1];
|
||||
fir[0] += weights[1] * val1;
|
||||
fir[1] += weights[2] * val1;
|
||||
fir[2] += weights[3] * val1;
|
||||
fir[3] += weights[4] * val1;
|
||||
|
||||
for ( xx = 2; xx < width; xx++ )
|
||||
{
|
||||
FT_UInt val, pix;
|
||||
|
||||
|
||||
val = line[xx];
|
||||
pix = fir[0] + weights[0] * val;
|
||||
fir[0] = fir[1] + weights[1] * val;
|
||||
fir[1] = fir[2] + weights[2] * val;
|
||||
fir[2] = fir[3] + weights[3] * val;
|
||||
fir[3] = weights[4] * val;
|
||||
|
||||
pix >>= 8;
|
||||
pix |= -( pix >> 8 );
|
||||
line[xx - 2] = (FT_Byte)pix;
|
||||
}
|
||||
|
||||
{
|
||||
FT_UInt pix;
|
||||
|
||||
|
||||
pix = fir[0] >> 8;
|
||||
pix |= -( pix >> 8 );
|
||||
line[xx - 2] = (FT_Byte)pix;
|
||||
|
||||
pix = fir[1] >> 8;
|
||||
pix |= -( pix >> 8 );
|
||||
line[xx - 1] = (FT_Byte)pix;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* vertical in-place FIR filter */
|
||||
else if ( mode == FT_RENDER_MODE_LCD_V && height >= 4 )
|
||||
{
|
||||
FT_Byte* column = bitmap->buffer;
|
||||
FT_Int pitch = bitmap->pitch;
|
||||
|
||||
|
||||
for ( ; width > 0; width--, column++ )
|
||||
{
|
||||
FT_Byte* col = column;
|
||||
FT_UInt fir[5];
|
||||
FT_UInt val1, yy;
|
||||
|
||||
|
||||
val1 = col[0];
|
||||
fir[0] = weights[2] * val1;
|
||||
fir[1] = weights[3] * val1;
|
||||
fir[2] = weights[4] * val1;
|
||||
fir[3] = 0;
|
||||
fir[4] = 0;
|
||||
col += pitch;
|
||||
|
||||
val1 = col[0];
|
||||
fir[0] += weights[1] * val1;
|
||||
fir[1] += weights[2] * val1;
|
||||
fir[2] += weights[3] * val1;
|
||||
fir[3] += weights[4] * val1;
|
||||
col += pitch;
|
||||
|
||||
for ( yy = 2; yy < height; yy++ )
|
||||
{
|
||||
FT_UInt val, pix;
|
||||
|
||||
|
||||
val = col[0];
|
||||
pix = fir[0] + weights[0] * val;
|
||||
fir[0] = fir[1] + weights[1] * val;
|
||||
fir[1] = fir[2] + weights[2] * val;
|
||||
fir[2] = fir[3] + weights[3] * val;
|
||||
fir[3] = weights[4] * val;
|
||||
|
||||
pix >>= 8;
|
||||
pix |= -( pix >> 8 );
|
||||
col[-2 * pitch] = (FT_Byte)pix;
|
||||
col += pitch;
|
||||
}
|
||||
|
||||
{
|
||||
FT_UInt pix;
|
||||
|
||||
|
||||
pix = fir[0] >> 8;
|
||||
pix |= -( pix >> 8 );
|
||||
col[-2 * pitch] = (FT_Byte)pix;
|
||||
|
||||
pix = fir[1] >> 8;
|
||||
pix |= -( pix >> 8 );
|
||||
col[-pitch] = (FT_Byte)pix;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
#ifdef USE_LEGACY
|
||||
|
||||
/* FIR filter used by the default and light filters */
|
||||
static void
|
||||
_ft_lcd_filter_legacy( FT_Bitmap* bitmap,
|
||||
FT_Render_Mode mode,
|
||||
FT_Library library )
|
||||
{
|
||||
FT_UInt width = (FT_UInt)bitmap->width;
|
||||
FT_UInt height = (FT_UInt)bitmap->rows;
|
||||
FT_Int pitch = bitmap->pitch;
|
||||
|
||||
static const int filters[3][3] =
|
||||
{
|
||||
{ 65538 * 9/13, 65538 * 1/6, 65538 * 1/13 },
|
||||
{ 65538 * 3/13, 65538 * 4/6, 65538 * 3/13 },
|
||||
{ 65538 * 1/13, 65538 * 1/6, 65538 * 9/13 }
|
||||
};
|
||||
|
||||
FT_UNUSED( library );
|
||||
|
||||
|
||||
/* horizontal in-place FIR filter */
|
||||
if ( mode == FT_RENDER_MODE_LCD && width >= 3 )
|
||||
{
|
||||
FT_Byte* line = bitmap->buffer;
|
||||
|
||||
|
||||
for ( ; height > 0; height--, line += pitch )
|
||||
{
|
||||
FT_UInt xx;
|
||||
|
||||
|
||||
for ( xx = 0; xx < width; xx += 3 )
|
||||
{
|
||||
FT_UInt r = 0;
|
||||
FT_UInt g = 0;
|
||||
FT_UInt b = 0;
|
||||
FT_UInt p;
|
||||
|
||||
|
||||
p = line[xx];
|
||||
r += filters[0][0] * p;
|
||||
g += filters[0][1] * p;
|
||||
b += filters[0][2] * p;
|
||||
|
||||
p = line[xx + 1];
|
||||
r += filters[1][0] * p;
|
||||
g += filters[1][1] * p;
|
||||
b += filters[1][2] * p;
|
||||
|
||||
p = line[xx + 2];
|
||||
r += filters[2][0] * p;
|
||||
g += filters[2][1] * p;
|
||||
b += filters[2][2] * p;
|
||||
|
||||
line[xx] = (FT_Byte)( r / 65536 );
|
||||
line[xx + 1] = (FT_Byte)( g / 65536 );
|
||||
line[xx + 2] = (FT_Byte)( b / 65536 );
|
||||
}
|
||||
}
|
||||
}
|
||||
else if ( mode == FT_RENDER_MODE_LCD_V && height >= 3 )
|
||||
{
|
||||
FT_Byte* column = bitmap->buffer;
|
||||
|
||||
|
||||
for ( ; width > 0; width--, column++ )
|
||||
{
|
||||
FT_Byte* col = column;
|
||||
FT_Byte* col_end = col + height * pitch;
|
||||
|
||||
|
||||
for ( ; col < col_end; col += 3 * pitch )
|
||||
{
|
||||
FT_UInt r = 0;
|
||||
FT_UInt g = 0;
|
||||
FT_UInt b = 0;
|
||||
FT_UInt p;
|
||||
|
||||
|
||||
p = col[0];
|
||||
r += filters[0][0] * p;
|
||||
g += filters[0][1] * p;
|
||||
b += filters[0][2] * p;
|
||||
|
||||
p = col[pitch];
|
||||
r += filters[1][0] * p;
|
||||
g += filters[1][1] * p;
|
||||
b += filters[1][2] * p;
|
||||
|
||||
p = col[pitch * 2];
|
||||
r += filters[2][0] * p;
|
||||
g += filters[2][1] * p;
|
||||
b += filters[2][2] * p;
|
||||
|
||||
col[0] = (FT_Byte)( r / 65536 );
|
||||
col[pitch] = (FT_Byte)( g / 65536 );
|
||||
col[2 * pitch] = (FT_Byte)( b / 65536 );
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#endif /* USE_LEGACY */
|
||||
|
||||
|
||||
FT_EXPORT( FT_Error )
|
||||
FT_Library_SetLcdFilter( FT_Library library,
|
||||
FT_LcdFilter filter )
|
||||
{
|
||||
static const FT_Byte light_filter[5] =
|
||||
{ 0, 85, 86, 85, 0 };
|
||||
/* the values here sum up to a value larger than 256, */
|
||||
/* providing a cheap gamma correction */
|
||||
static const FT_Byte default_filter[5] =
|
||||
{ 0x10, 0x40, 0x70, 0x40, 0x10 };
|
||||
|
||||
|
||||
if ( library == NULL )
|
||||
return FT_Err_Invalid_Argument;
|
||||
|
||||
switch ( filter )
|
||||
{
|
||||
case FT_LCD_FILTER_NONE:
|
||||
library->lcd_filter_func = NULL;
|
||||
library->lcd_extra = 0;
|
||||
break;
|
||||
|
||||
case FT_LCD_FILTER_DEFAULT:
|
||||
#if defined( FT_FORCE_LEGACY_LCD_FILTER )
|
||||
|
||||
library->lcd_filter_func = _ft_lcd_filter_legacy;
|
||||
library->lcd_extra = 0;
|
||||
|
||||
#elif defined( FT_FORCE_LIGHT_LCD_FILTER )
|
||||
|
||||
memcpy( library->lcd_weights, light_filter, 5 );
|
||||
library->lcd_filter_func = _ft_lcd_filter_fir;
|
||||
library->lcd_extra = 2;
|
||||
|
||||
#else
|
||||
|
||||
memcpy( library->lcd_weights, default_filter, 5 );
|
||||
library->lcd_filter_func = _ft_lcd_filter_fir;
|
||||
library->lcd_extra = 2;
|
||||
|
||||
#endif
|
||||
|
||||
break;
|
||||
|
||||
case FT_LCD_FILTER_LIGHT:
|
||||
memcpy( library->lcd_weights, light_filter, 5 );
|
||||
library->lcd_filter_func = _ft_lcd_filter_fir;
|
||||
library->lcd_extra = 2;
|
||||
break;
|
||||
|
||||
#ifdef USE_LEGACY
|
||||
|
||||
case FT_LCD_FILTER_LEGACY:
|
||||
library->lcd_filter_func = _ft_lcd_filter_legacy;
|
||||
library->lcd_extra = 0;
|
||||
break;
|
||||
|
||||
#endif
|
||||
|
||||
default:
|
||||
return FT_Err_Invalid_Argument;
|
||||
}
|
||||
|
||||
library->lcd_filter = filter;
|
||||
return 0;
|
||||
}
|
||||
|
||||
#else /* !FT_CONFIG_OPTION_SUBPIXEL_RENDERING */
|
||||
|
||||
FT_EXPORT( FT_Error )
|
||||
FT_Library_SetLcdFilter( FT_Library library,
|
||||
FT_LcdFilter filter )
|
||||
{
|
||||
FT_UNUSED( library );
|
||||
FT_UNUSED( filter );
|
||||
|
||||
return FT_Err_Unimplemented_Feature;
|
||||
}
|
||||
|
||||
#endif /* !FT_CONFIG_OPTION_SUBPIXEL_RENDERING */
|
||||
|
||||
|
||||
/* END */
|
@ -3,7 +3,10 @@
|
||||
/* ftmac.c */
|
||||
/* */
|
||||
/* Mac FOND support. Written by just@letterror.com. */
|
||||
/* Heavily Fixed by mpsuzuki, George Williams and Sean McBride */
|
||||
/* Heavily modified by mpsuzuki, George Williams, and Sean McBride. */
|
||||
/* */
|
||||
/* This file is for Mac OS X only; see builds/mac/ftoldmac.c for */
|
||||
/* classic platforms built by MPW. */
|
||||
/* */
|
||||
/* Copyright 1996-2001, 2002, 2003, 2004, 2005, 2006 by */
|
||||
/* Just van Rossum, David Turner, Robert Wilhelm, and Werner Lemberg. */
|
||||
@ -53,6 +56,12 @@
|
||||
- If there is a TrueType font (an `sfnt' resource), read it into memory,
|
||||
wrap it into a memory stream, load the TrueType driver and delegate
|
||||
the rest of the work to it, by calling FT_Open_Face().
|
||||
|
||||
- Some suitcase fonts (notably Onyx) might point the `LWFN' file to
|
||||
itself, even though it doesn't contains `POST' resources. To handle
|
||||
this special case without opening the file an extra time, we just
|
||||
ignore errors from the `LWFN' and fallback to the `sfnt' if both are
|
||||
available.
|
||||
*/
|
||||
|
||||
|
||||
@ -60,67 +69,25 @@
|
||||
#include FT_FREETYPE_H
|
||||
#include FT_INTERNAL_STREAM_H
|
||||
|
||||
#if defined( __GNUC__ ) || defined( __IBMC__ )
|
||||
/* This is for Mac OS X. Without redefinition, OS_INLINE */
|
||||
/* expands to `static inline' which doesn't survive the */
|
||||
/* -ansi compilation flag of GCC. */
|
||||
#undef OS_INLINE
|
||||
#define OS_INLINE static __inline__
|
||||
#include <Carbon/Carbon.h>
|
||||
#else
|
||||
#include <Resources.h>
|
||||
#include <Fonts.h>
|
||||
#include <Errors.h>
|
||||
#include <Files.h>
|
||||
#include <TextUtils.h>
|
||||
#endif
|
||||
|
||||
#if defined( __MWERKS__ ) && !TARGET_RT_MAC_MACHO
|
||||
#include <FSp_fopen.h>
|
||||
#endif
|
||||
|
||||
#include FT_MAC_H
|
||||
|
||||
|
||||
/* FSSpec functions are deprecated since Mac OS X 10.4 */
|
||||
#ifndef HAVE_FSSPEC
|
||||
#if TARGET_API_MAC_OS8 || TARGET_API_MAC_CARBON
|
||||
#define HAVE_FSSPEC 1
|
||||
#else
|
||||
#define HAVE_FSSPEC 0
|
||||
#endif
|
||||
#endif
|
||||
|
||||
/* most FSRef functions were introduced since Mac OS 9 */
|
||||
#ifndef HAVE_FSREF
|
||||
#if TARGET_API_MAC_OSX
|
||||
#define HAVE_FSREF 1
|
||||
#else
|
||||
#define HAVE_FSREF 0
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#ifndef HFS_MAXPATHLEN
|
||||
#define HFS_MAXPATHLEN 1024
|
||||
#endif
|
||||
|
||||
|
||||
/* QuickDraw is deprecated since Mac OS X 10.4 */
|
||||
#ifndef HAVE_QUICKDRAW_CARBON
|
||||
#if TARGET_API_MAC_OS8 || TARGET_API_MAC_CARBON
|
||||
#define HAVE_QUICKDRAW_CARBON 1
|
||||
#else
|
||||
#define HAVE_QUICKDRAW_CARBON 0
|
||||
#endif
|
||||
#endif
|
||||
#include FT_MAC_H
|
||||
|
||||
/* undefine blocking-macros in ftmac.h */
|
||||
#undef FT_GetFile_From_Mac_Name( a, b, c )
|
||||
#undef FT_GetFile_From_Mac_ATS_Name( a, b, c )
|
||||
#undef FT_New_Face_From_FSSpec( a, b, c, d )
|
||||
|
||||
/* AppleTypeService is available since Mac OS X */
|
||||
#ifndef HAVE_ATS
|
||||
#if TARGET_API_MAC_OSX
|
||||
#define HAVE_ATS 1
|
||||
#else
|
||||
#define HAVE_ATS 0
|
||||
#endif
|
||||
#endif
|
||||
|
||||
/* Set PREFER_LWFN to 1 if LWFN (Type 1) is preferred over
|
||||
TrueType in case *both* are available (this is not common,
|
||||
@ -130,8 +97,6 @@
|
||||
#endif
|
||||
|
||||
|
||||
#if !HAVE_QUICKDRAW_CARBON /* QuickDraw is deprecated since Mac OS X 10.4 */
|
||||
|
||||
FT_EXPORT_DEF( FT_Error )
|
||||
FT_GetFile_From_Mac_Name( const char* fontName,
|
||||
FSSpec* pathSpec,
|
||||
@ -140,106 +105,6 @@
|
||||
return FT_Err_Unimplemented_Feature;
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
FT_EXPORT_DEF( FT_Error )
|
||||
FT_GetFile_From_Mac_Name( const char* fontName,
|
||||
FSSpec* pathSpec,
|
||||
FT_Long* face_index )
|
||||
{
|
||||
OptionBits options = kFMUseGlobalScopeOption;
|
||||
|
||||
FMFontFamilyIterator famIter;
|
||||
OSStatus status = FMCreateFontFamilyIterator( NULL, NULL,
|
||||
options,
|
||||
&famIter );
|
||||
FMFont the_font = 0;
|
||||
FMFontFamily family = 0;
|
||||
|
||||
|
||||
*face_index = 0;
|
||||
while ( status == 0 && !the_font )
|
||||
{
|
||||
status = FMGetNextFontFamily( &famIter, &family );
|
||||
if ( status == 0 )
|
||||
{
|
||||
int stat2;
|
||||
FMFontFamilyInstanceIterator instIter;
|
||||
Str255 famNameStr;
|
||||
char famName[256];
|
||||
|
||||
|
||||
/* get the family name */
|
||||
FMGetFontFamilyName( family, famNameStr );
|
||||
CopyPascalStringToC( famNameStr, famName );
|
||||
|
||||
/* iterate through the styles */
|
||||
FMCreateFontFamilyInstanceIterator( family, &instIter );
|
||||
|
||||
*face_index = 0;
|
||||
stat2 = 0;
|
||||
|
||||
while ( stat2 == 0 && !the_font )
|
||||
{
|
||||
FMFontStyle style;
|
||||
FMFontSize size;
|
||||
FMFont font;
|
||||
|
||||
|
||||
stat2 = FMGetNextFontFamilyInstance( &instIter, &font,
|
||||
&style, &size );
|
||||
if ( stat2 == 0 && size == 0 )
|
||||
{
|
||||
char fullName[256];
|
||||
|
||||
|
||||
/* build up a complete face name */
|
||||
ft_strcpy( fullName, famName );
|
||||
if ( style & bold )
|
||||
ft_strcat( fullName, " Bold" );
|
||||
if ( style & italic )
|
||||
ft_strcat( fullName, " Italic" );
|
||||
|
||||
/* compare with the name we are looking for */
|
||||
if ( ft_strcmp( fullName, fontName ) == 0 )
|
||||
{
|
||||
/* found it! */
|
||||
the_font = font;
|
||||
}
|
||||
else
|
||||
++(*face_index);
|
||||
}
|
||||
}
|
||||
|
||||
FMDisposeFontFamilyInstanceIterator( &instIter );
|
||||
}
|
||||
}
|
||||
|
||||
FMDisposeFontFamilyIterator( &famIter );
|
||||
|
||||
if ( the_font )
|
||||
{
|
||||
FMGetFontContainer( the_font, pathSpec );
|
||||
return FT_Err_Ok;
|
||||
}
|
||||
else
|
||||
return FT_Err_Unknown_File_Format;
|
||||
}
|
||||
|
||||
#endif /* HAVE_QUICKDRAW_CARBON */
|
||||
|
||||
|
||||
#if !HAVE_ATS
|
||||
|
||||
FT_EXPORT_DEF( FT_Error )
|
||||
FT_GetFile_From_Mac_ATS_Name( const char* fontName,
|
||||
FSSpec* pathSpec,
|
||||
FT_Long* face_index )
|
||||
{
|
||||
return FT_Err_Unimplemented_Feature;
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
FT_EXPORT_DEF( FT_Error )
|
||||
FT_GetFile_From_Mac_ATS_Name( const char* fontName,
|
||||
@ -287,143 +152,11 @@
|
||||
return FT_Err_Ok;
|
||||
}
|
||||
|
||||
#endif /* HAVE_ATS */
|
||||
|
||||
|
||||
#if defined( __MWERKS__ ) && !TARGET_RT_MAC_MACHO
|
||||
|
||||
#define STREAM_FILE( stream ) ( (FT_FILE*)stream->descriptor.pointer )
|
||||
|
||||
|
||||
FT_CALLBACK_DEF( void )
|
||||
ft_FSp_stream_close( FT_Stream stream )
|
||||
{
|
||||
ft_fclose( STREAM_FILE( stream ) );
|
||||
|
||||
stream->descriptor.pointer = NULL;
|
||||
stream->size = 0;
|
||||
stream->base = 0;
|
||||
}
|
||||
|
||||
|
||||
FT_CALLBACK_DEF( unsigned long )
|
||||
ft_FSp_stream_io( FT_Stream stream,
|
||||
unsigned long offset,
|
||||
unsigned char* buffer,
|
||||
unsigned long count )
|
||||
{
|
||||
FT_FILE* file;
|
||||
|
||||
|
||||
file = STREAM_FILE( stream );
|
||||
|
||||
ft_fseek( file, offset, SEEK_SET );
|
||||
|
||||
return (unsigned long)ft_fread( buffer, 1, count, file );
|
||||
}
|
||||
|
||||
#endif /* __MWERKS__ && !TARGET_RT_MAC_MACHO */
|
||||
|
||||
|
||||
#if HAVE_FSSPEC && !HAVE_FSREF
|
||||
|
||||
static OSErr
|
||||
FT_FSPathMakeSpec( const UInt8* pathname,
|
||||
FSSpec* spec_p,
|
||||
Boolean isDirectory )
|
||||
{
|
||||
const char *p, *q;
|
||||
short vRefNum;
|
||||
long dirID;
|
||||
Str255 nodeName;
|
||||
OSErr err;
|
||||
|
||||
|
||||
p = q = (const char *)pathname;
|
||||
dirID = 0;
|
||||
vRefNum = 0;
|
||||
|
||||
while ( 1 )
|
||||
{
|
||||
q = p + FT_MIN( 255, ft_strlen( p ) );
|
||||
|
||||
if ( q == p )
|
||||
return 0;
|
||||
|
||||
if ( 255 < ft_strlen( (char *)pathname ) )
|
||||
{
|
||||
while ( p < q && *q != ':' )
|
||||
q--;
|
||||
}
|
||||
|
||||
if ( p < q )
|
||||
*(char *)nodeName = q - p;
|
||||
else if ( ft_strlen( p ) < 256 )
|
||||
*(char *)nodeName = ft_strlen( p );
|
||||
else
|
||||
return errFSNameTooLong;
|
||||
|
||||
ft_strncpy( (char *)nodeName + 1, (char *)p, *(char *)nodeName );
|
||||
err = FSMakeFSSpec( vRefNum, dirID, nodeName, spec_p );
|
||||
if ( err || '\0' == *q )
|
||||
return err;
|
||||
|
||||
vRefNum = spec_p->vRefNum;
|
||||
dirID = spec_p->parID;
|
||||
|
||||
p = q;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static OSErr
|
||||
FT_FSpMakePath( const FSSpec* spec_p,
|
||||
UInt8* path,
|
||||
UInt32 maxPathSize )
|
||||
{
|
||||
OSErr err;
|
||||
FSSpec spec = *spec_p;
|
||||
short vRefNum;
|
||||
long dirID;
|
||||
Str255 parDir_name;
|
||||
|
||||
|
||||
FT_MEM_SET( path, 0, maxPathSize );
|
||||
while ( 1 )
|
||||
{
|
||||
int child_namelen = ft_strlen( (char *)path );
|
||||
unsigned char node_namelen = spec.name[0];
|
||||
unsigned char* node_name = spec.name + 1;
|
||||
|
||||
|
||||
if ( node_namelen + child_namelen > maxPathSize )
|
||||
return errFSNameTooLong;
|
||||
|
||||
FT_MEM_MOVE( path + node_namelen + 1, path, child_namelen );
|
||||
FT_MEM_COPY( path, node_name, node_namelen );
|
||||
if ( child_namelen > 0 )
|
||||
path[node_namelen] = ':';
|
||||
|
||||
vRefNum = spec.vRefNum;
|
||||
dirID = spec.parID;
|
||||
parDir_name[0] = '\0';
|
||||
err = FSMakeFSSpec( vRefNum, dirID, parDir_name, &spec );
|
||||
if ( noErr != err || dirID == spec.parID )
|
||||
break;
|
||||
}
|
||||
return noErr;
|
||||
}
|
||||
|
||||
#endif /* HAVE_FSSPEC && !HAVE_FSREF */
|
||||
|
||||
|
||||
static OSErr
|
||||
FT_FSPathMakeRes( const UInt8* pathname,
|
||||
short* res )
|
||||
{
|
||||
|
||||
#if HAVE_FSREF
|
||||
|
||||
OSErr err;
|
||||
FSRef ref;
|
||||
|
||||
@ -440,22 +173,6 @@
|
||||
*res = FSOpenResFile( &ref, fsRdPerm );
|
||||
err = ResError();
|
||||
|
||||
#else
|
||||
|
||||
OSErr err;
|
||||
FSSpec spec;
|
||||
|
||||
|
||||
if ( noErr != FT_FSPathMakeSpec( pathname, &spec, FALSE ) )
|
||||
return FT_Err_Cannot_Open_Resource;
|
||||
|
||||
/* at present, no support for dfont format without FSRef */
|
||||
/* (see above), try original resource-fork font */
|
||||
*res = FSpOpenResFile( &spec, fsRdPerm );
|
||||
err = ResError();
|
||||
|
||||
#endif /* HAVE_FSREF */
|
||||
|
||||
return err;
|
||||
}
|
||||
|
||||
@ -464,9 +181,6 @@
|
||||
static OSType
|
||||
get_file_type_from_path( const UInt8* pathname )
|
||||
{
|
||||
|
||||
#if HAVE_FSREF
|
||||
|
||||
FSRef ref;
|
||||
FSCatalogInfo info;
|
||||
|
||||
@ -479,23 +193,6 @@
|
||||
return ( OSType ) 0;
|
||||
|
||||
return ((FInfo *)(info.finderInfo))->fdType;
|
||||
|
||||
#else
|
||||
|
||||
FSSpec spec;
|
||||
FInfo finfo;
|
||||
|
||||
|
||||
if ( noErr != FT_FSPathMakeSpec( pathname, &spec, FALSE ) )
|
||||
return ( OSType ) 0;
|
||||
|
||||
if ( noErr != FSpGetFInfo( &spec, &finfo ) )
|
||||
return ( OSType ) 0;
|
||||
|
||||
return finfo.fdType;
|
||||
|
||||
#endif /* HAVE_FSREF */
|
||||
|
||||
}
|
||||
|
||||
|
||||
@ -536,7 +233,8 @@
|
||||
/* The count is 1 greater than the value in the FOND. */
|
||||
/* Isn't that cute? :-) */
|
||||
|
||||
return 1 + *( (short*)( fond_data + sizeof ( FamRec ) ) );
|
||||
return EndianS16_BtoN( *( (short*)( fond_data +
|
||||
sizeof ( FamRec ) ) ) ) + 1;
|
||||
}
|
||||
|
||||
|
||||
@ -549,13 +247,14 @@
|
||||
|
||||
|
||||
fond = (FamRec*)fond_data;
|
||||
face_all = *( (short *)( fond_data + sizeof ( FamRec ) ) ) + 1;
|
||||
face_all = EndianS16_BtoN( *( (short *)( fond_data +
|
||||
sizeof ( FamRec ) ) ) ) + 1;
|
||||
assoc = (AsscEntry*)( fond_data + sizeof ( FamRec ) + 2 );
|
||||
face = 0;
|
||||
|
||||
for ( i = 0; i < face_all; i++ )
|
||||
{
|
||||
if ( 0 == assoc[i].fontSize )
|
||||
if ( 0 == EndianS16_BtoN( assoc[i].fontSize ) )
|
||||
face++;
|
||||
}
|
||||
return face;
|
||||
@ -597,19 +296,19 @@
|
||||
|
||||
/* if the face at this index is not scalable,
|
||||
fall back to the first one (old behavior) */
|
||||
if ( assoc->fontSize == 0 )
|
||||
if ( EndianS16_BtoN( assoc->fontSize ) == 0 )
|
||||
{
|
||||
*have_sfnt = 1;
|
||||
*sfnt_id = assoc->fontID;
|
||||
*sfnt_id = EndianS16_BtoN( assoc->fontID );
|
||||
}
|
||||
else if ( base_assoc->fontSize == 0 )
|
||||
{
|
||||
*have_sfnt = 1;
|
||||
*sfnt_id = base_assoc->fontID;
|
||||
*sfnt_id = EndianS16_BtoN( base_assoc->fontID );
|
||||
}
|
||||
}
|
||||
|
||||
if ( fond->ffStylOff )
|
||||
if ( EndianS32_BtoN( fond->ffStylOff ) )
|
||||
{
|
||||
unsigned char* p = (unsigned char*)fond_data;
|
||||
StyleTable* style;
|
||||
@ -619,10 +318,10 @@
|
||||
int i;
|
||||
|
||||
|
||||
p += fond->ffStylOff;
|
||||
p += EndianS32_BtoN( fond->ffStylOff );
|
||||
style = (StyleTable*)p;
|
||||
p += sizeof ( StyleTable );
|
||||
string_count = *(unsigned short*)(p);
|
||||
string_count = EndianS16_BtoN( *(short*)(p) );
|
||||
p += sizeof ( short );
|
||||
|
||||
for ( i = 0; i < string_count && i < 64; i++ )
|
||||
@ -679,9 +378,6 @@
|
||||
UInt8* path_lwfn,
|
||||
int path_size )
|
||||
{
|
||||
|
||||
#if HAVE_FSREF
|
||||
|
||||
FSRef ref, par_ref;
|
||||
int dirname_len;
|
||||
|
||||
@ -720,44 +416,6 @@
|
||||
return FT_Err_Cannot_Open_Resource;
|
||||
|
||||
return FT_Err_Ok;
|
||||
|
||||
#else
|
||||
|
||||
int i;
|
||||
FSSpec spec;
|
||||
|
||||
|
||||
/* pathname for FSSpec is always HFS format */
|
||||
if ( ft_strlen( (char *)path_fond ) > path_size )
|
||||
return FT_Err_Invalid_Argument;
|
||||
|
||||
ft_strcpy( (char *)path_lwfn, (char *)path_fond );
|
||||
|
||||
i = ft_strlen( (char *)path_lwfn ) - 1;
|
||||
while ( i > 0 && ':' != path_lwfn[i] )
|
||||
i--;
|
||||
|
||||
if ( i + 1 + base_lwfn[0] > path_size )
|
||||
return FT_Err_Invalid_Argument;
|
||||
|
||||
if ( ':' == path_lwfn[i] )
|
||||
{
|
||||
ft_strcpy( (char *)path_lwfn + i + 1, (char *)base_lwfn + 1 );
|
||||
path_lwfn[i + 1 + base_lwfn[0]] = '\0';
|
||||
}
|
||||
else
|
||||
{
|
||||
ft_strcpy( (char *)path_lwfn, (char *)base_lwfn + 1 );
|
||||
path_lwfn[base_lwfn[0]] = '\0';
|
||||
}
|
||||
|
||||
if ( noErr != FT_FSPathMakeSpec( path_lwfn, &spec, FALSE ) )
|
||||
return FT_Err_Cannot_Open_Resource;
|
||||
|
||||
return FT_Err_Ok;
|
||||
|
||||
#endif /* HAVE_FSREF */
|
||||
|
||||
}
|
||||
|
||||
|
||||
@ -770,13 +428,13 @@
|
||||
Str255 lwfn_file_name;
|
||||
UInt8 buff[HFS_MAXPATHLEN];
|
||||
FT_Error err;
|
||||
short num_faces;
|
||||
|
||||
|
||||
have_sfnt = have_lwfn = 0;
|
||||
|
||||
HLock( fond );
|
||||
parse_fond( *fond, &have_sfnt, &sfnt_id, lwfn_file_name, 0 );
|
||||
HUnlock( fond );
|
||||
|
||||
if ( lwfn_file_name[0] )
|
||||
{
|
||||
@ -787,9 +445,12 @@
|
||||
}
|
||||
|
||||
if ( have_lwfn && ( !have_sfnt || PREFER_LWFN ) )
|
||||
return 1;
|
||||
num_faces = 1;
|
||||
else
|
||||
return count_faces_scalable( *fond );
|
||||
num_faces = count_faces_scalable( *fond );
|
||||
|
||||
HUnlock( fond );
|
||||
return num_faces;
|
||||
}
|
||||
|
||||
|
||||
@ -1010,6 +671,8 @@
|
||||
error = FT_Open_Face( library, &args, face_index, aface );
|
||||
if ( error == FT_Err_Ok )
|
||||
(*aface)->face_flags &= ~FT_FACE_FLAG_EXTERNAL_STREAM;
|
||||
else
|
||||
FT_Stream_Free( stream, 0 );
|
||||
|
||||
return error;
|
||||
}
|
||||
@ -1150,7 +813,7 @@
|
||||
Str255 lwfn_file_name;
|
||||
UInt8 path_lwfn[HFS_MAXPATHLEN];
|
||||
OSErr err;
|
||||
FT_Error error;
|
||||
FT_Error error = FT_Err_Ok;
|
||||
|
||||
|
||||
GetResInfo( fond, &fond_id, &fond_type, fond_name );
|
||||
@ -1170,8 +833,6 @@
|
||||
if ( noErr != ResError() )
|
||||
goto found_no_lwfn_file;
|
||||
|
||||
#if HAVE_FSREF
|
||||
|
||||
{
|
||||
UInt8 path_fond[HFS_MAXPATHLEN];
|
||||
FSRef ref;
|
||||
@ -1191,61 +852,24 @@
|
||||
if ( FT_Err_Ok == error )
|
||||
have_lwfn = 1;
|
||||
}
|
||||
|
||||
#elif HAVE_FSSPEC
|
||||
|
||||
{
|
||||
UInt8 path_fond[HFS_MAXPATHLEN];
|
||||
FCBPBRec pb;
|
||||
Str255 fond_file_name;
|
||||
FSSpec spec;
|
||||
|
||||
|
||||
FT_MEM_SET( &spec, 0, sizeof ( FSSpec ) );
|
||||
FT_MEM_SET( &pb, 0, sizeof ( FCBPBRec ) );
|
||||
|
||||
pb.ioNamePtr = fond_file_name;
|
||||
pb.ioVRefNum = 0;
|
||||
pb.ioRefNum = res;
|
||||
pb.ioFCBIndx = 0;
|
||||
|
||||
err = PBGetFCBInfoSync( &pb );
|
||||
if ( noErr != err )
|
||||
goto found_no_lwfn_file;
|
||||
|
||||
err = FSMakeFSSpec( pb.ioFCBVRefNum, pb.ioFCBParID,
|
||||
fond_file_name, &spec );
|
||||
if ( noErr != err )
|
||||
goto found_no_lwfn_file;
|
||||
|
||||
err = FT_FSpMakePath( &spec, path_fond, sizeof ( path_fond ) );
|
||||
if ( noErr != err )
|
||||
goto found_no_lwfn_file;
|
||||
|
||||
error = lookup_lwfn_by_fond( path_fond, lwfn_file_name,
|
||||
path_lwfn, sizeof ( path_lwfn ) );
|
||||
if ( FT_Err_Ok == error )
|
||||
have_lwfn = 1;
|
||||
}
|
||||
|
||||
#endif /* HAVE_FSREF, HAVE_FSSPEC */
|
||||
|
||||
}
|
||||
|
||||
if ( have_lwfn && ( !have_sfnt || PREFER_LWFN ) )
|
||||
return FT_New_Face_From_LWFN( library,
|
||||
path_lwfn,
|
||||
face_index,
|
||||
aface );
|
||||
error = FT_New_Face_From_LWFN( library,
|
||||
path_lwfn,
|
||||
face_index,
|
||||
aface );
|
||||
else
|
||||
error = FT_Err_Unknown_File_Format;
|
||||
|
||||
found_no_lwfn_file:
|
||||
if ( have_sfnt )
|
||||
return FT_New_Face_From_SFNT( library,
|
||||
sfnt_id,
|
||||
face_index,
|
||||
aface );
|
||||
if ( have_sfnt && FT_Err_Ok != error )
|
||||
error = FT_New_Face_From_SFNT( library,
|
||||
sfnt_id,
|
||||
face_index,
|
||||
aface );
|
||||
|
||||
return FT_Err_Unknown_File_Format;
|
||||
return error;
|
||||
}
|
||||
|
||||
|
||||
@ -1336,13 +960,6 @@
|
||||
FT_Long face_index,
|
||||
FT_Face* aface )
|
||||
{
|
||||
|
||||
#if !HAVE_FSREF
|
||||
|
||||
return FT_Err_Unimplemented_Feature;
|
||||
|
||||
#else
|
||||
|
||||
FT_Error error;
|
||||
FT_Open_Args args;
|
||||
OSErr err;
|
||||
@ -1364,9 +981,6 @@
|
||||
args.flags = FT_OPEN_PATHNAME;
|
||||
args.pathname = (char*)pathname;
|
||||
return FT_Open_Face( library, &args, face_index, aface );
|
||||
|
||||
#endif /* HAVE_FSREF */
|
||||
|
||||
}
|
||||
|
||||
|
||||
@ -1385,9 +999,6 @@
|
||||
FT_Long face_index,
|
||||
FT_Face* aface )
|
||||
{
|
||||
|
||||
#if HAVE_FSREF
|
||||
|
||||
FSRef ref;
|
||||
|
||||
|
||||
@ -1395,37 +1006,6 @@
|
||||
return FT_Err_Invalid_Argument;
|
||||
else
|
||||
return FT_New_Face_From_FSRef( library, &ref, face_index, aface );
|
||||
|
||||
#elif HAVE_FSSPEC
|
||||
|
||||
FT_Error error;
|
||||
FT_Open_Args args;
|
||||
OSErr err;
|
||||
UInt8 pathname[HFS_MAXPATHLEN];
|
||||
|
||||
|
||||
if ( !spec )
|
||||
return FT_Err_Invalid_Argument;
|
||||
|
||||
err = FT_FSpMakePath( spec, pathname, sizeof ( pathname ) );
|
||||
if ( err )
|
||||
error = FT_Err_Cannot_Open_Resource;
|
||||
|
||||
error = FT_New_Face_From_Resource( library, pathname, face_index, aface );
|
||||
if ( error != 0 || *aface != NULL )
|
||||
return error;
|
||||
|
||||
/* fallback to datafork font */
|
||||
args.flags = FT_OPEN_PATHNAME;
|
||||
args.pathname = (char*)pathname;
|
||||
return FT_Open_Face( library, &args, face_index, aface );
|
||||
|
||||
#else
|
||||
|
||||
return FT_Err_Unimplemented_Feature;
|
||||
|
||||
#endif /* HAVE_FSREF, HAVE_FSSPEC */
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
@ -174,7 +174,7 @@
|
||||
|
||||
|
||||
/* documentation is in ftmm.h */
|
||||
|
||||
|
||||
/* This is exactly the same as the previous function. It exists for */
|
||||
/* orthogonality. */
|
||||
|
||||
|
@ -4,7 +4,7 @@
|
||||
/* */
|
||||
/* The FreeType private base classes (body). */
|
||||
/* */
|
||||
/* Copyright 1996-2001, 2002, 2003, 2004, 2005, 2006 by */
|
||||
/* Copyright 1996-2001, 2002, 2003, 2004, 2005, 2006, 2007 by */
|
||||
/* David Turner, Robert Wilhelm, and Werner Lemberg. */
|
||||
/* */
|
||||
/* This file is part of the FreeType project, and may only be used, */
|
||||
@ -78,11 +78,10 @@
|
||||
FT_BASE_DEF( FT_Int )
|
||||
ft_validator_run( FT_Validator valid )
|
||||
{
|
||||
int result;
|
||||
/* This function doesn't work! None should call it. */
|
||||
FT_UNUSED( valid );
|
||||
|
||||
|
||||
result = ft_setjmp( valid->jump_buffer );
|
||||
return result;
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
||||
@ -90,8 +89,17 @@
|
||||
ft_validator_error( FT_Validator valid,
|
||||
FT_Error error )
|
||||
{
|
||||
/* since the cast below also disables the compiler's */
|
||||
/* type check, we introduce a dummy variable, which */
|
||||
/* will be optimized away */
|
||||
volatile jmp_buf* jump_buffer = &valid->jump_buffer;
|
||||
|
||||
|
||||
valid->error = error;
|
||||
ft_longjmp( valid->jump_buffer, 1 );
|
||||
|
||||
/* throw away volatileness; use `jump_buffer' or the */
|
||||
/* compiler may warn about an unused local variable */
|
||||
ft_longjmp( *(jmp_buf*) jump_buffer, 1 );
|
||||
}
|
||||
|
||||
|
||||
@ -541,8 +549,8 @@
|
||||
if ( !face || !face->size || !face->glyph )
|
||||
return FT_Err_Invalid_Face_Handle;
|
||||
|
||||
if ( glyph_index >= (FT_UInt)face->num_glyphs )
|
||||
return FT_Err_Invalid_Argument;
|
||||
/* The validity test for `glyph_index' is performed by the */
|
||||
/* font drivers. */
|
||||
|
||||
slot = face->glyph;
|
||||
ft_glyphslot_clear( slot );
|
||||
@ -565,22 +573,44 @@
|
||||
load_flags &= ~FT_LOAD_RENDER;
|
||||
}
|
||||
|
||||
if ( FT_LOAD_TARGET_MODE( load_flags ) == FT_RENDER_MODE_LIGHT )
|
||||
load_flags |= FT_LOAD_FORCE_AUTOHINT;
|
||||
/*
|
||||
* 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.
|
||||
*
|
||||
* - Then, autohint if FT_LOAD_FORCE_AUTOHINT is set
|
||||
* or if we don't have a native font hinter.
|
||||
*
|
||||
* - Otherwise, auto-hint for LIGHT hinting mode.
|
||||
*
|
||||
* - Exception: The font requires the unpatented
|
||||
* bytecode interpreter to load properly.
|
||||
*/
|
||||
|
||||
/* auto-hinter is preferred and should be used */
|
||||
if ( ( !FT_DRIVER_HAS_HINTER( driver ) ||
|
||||
( load_flags & FT_LOAD_FORCE_AUTOHINT ) ) &&
|
||||
!( load_flags & FT_LOAD_NO_HINTING ) &&
|
||||
!( load_flags & FT_LOAD_NO_AUTOHINT ) )
|
||||
autohint = 0;
|
||||
if ( hinter &&
|
||||
( load_flags & FT_LOAD_NO_HINTING ) == 0 &&
|
||||
( load_flags & FT_LOAD_NO_AUTOHINT ) == 0 &&
|
||||
FT_DRIVER_IS_SCALABLE( driver ) &&
|
||||
FT_DRIVER_USES_OUTLINES( driver ) &&
|
||||
face->internal->transform_matrix.yy > 0 &&
|
||||
face->internal->transform_matrix.yx == 0 )
|
||||
{
|
||||
/* check whether it works for this face */
|
||||
autohint =
|
||||
FT_BOOL( hinter &&
|
||||
FT_DRIVER_IS_SCALABLE( driver ) &&
|
||||
FT_DRIVER_USES_OUTLINES( driver ) &&
|
||||
face->internal->transform_matrix.yy > 0 &&
|
||||
face->internal->transform_matrix.yx == 0 );
|
||||
if ( ( load_flags & FT_LOAD_FORCE_AUTOHINT ) != 0 ||
|
||||
!FT_DRIVER_HAS_HINTER( driver ) )
|
||||
autohint = 1;
|
||||
else
|
||||
{
|
||||
FT_Render_Mode mode = FT_LOAD_TARGET_MODE( load_flags );
|
||||
|
||||
|
||||
if ( mode == FT_RENDER_MODE_LIGHT ||
|
||||
face->internal->ignore_unpatented_hinter )
|
||||
autohint = 1;
|
||||
}
|
||||
}
|
||||
|
||||
if ( autohint )
|
||||
@ -1341,6 +1371,7 @@
|
||||
FT_Long flag_offset;
|
||||
FT_Long rlen;
|
||||
int is_cff;
|
||||
FT_Long face_index_in_resource = 0;
|
||||
|
||||
|
||||
if ( face_index == -1 )
|
||||
@ -1372,7 +1403,7 @@
|
||||
error = open_face_from_buffer( library,
|
||||
sfnt_data,
|
||||
rlen,
|
||||
face_index,
|
||||
face_index_in_resource,
|
||||
is_cff ? "cff" : "truetype",
|
||||
aface );
|
||||
|
||||
@ -1414,6 +1445,9 @@
|
||||
error = Mac_Read_POST_Resource( library, stream, data_offsets, count,
|
||||
face_index, aface );
|
||||
FT_FREE( data_offsets );
|
||||
/* POST exists in an LWFN providing a single face */
|
||||
if ( !error )
|
||||
(*aface)->num_faces = 1;
|
||||
return error;
|
||||
}
|
||||
|
||||
@ -1423,9 +1457,14 @@
|
||||
&data_offsets, &count );
|
||||
if ( !error )
|
||||
{
|
||||
FT_Long face_index_internal = face_index % count;
|
||||
|
||||
|
||||
error = Mac_Read_sfnt_Resource( library, stream, data_offsets, count,
|
||||
face_index, aface );
|
||||
face_index_internal, aface );
|
||||
FT_FREE( data_offsets );
|
||||
if ( !error )
|
||||
(*aface)->num_faces = count;
|
||||
}
|
||||
|
||||
return error;
|
||||
@ -1531,7 +1570,7 @@
|
||||
|
||||
error = IsMacResource( library, stream2, offsets[i],
|
||||
face_index, aface );
|
||||
FT_Stream_Close( stream2 );
|
||||
FT_Stream_Free( stream2, 0 );
|
||||
|
||||
FT_TRACE3(( "%s\n", error ? "failed": "successful" ));
|
||||
|
||||
@ -2050,7 +2089,7 @@
|
||||
FT_Match_Size( FT_Face face,
|
||||
FT_Size_Request req,
|
||||
FT_Bool ignore_width,
|
||||
FT_ULong* index )
|
||||
FT_ULong* size_index )
|
||||
{
|
||||
FT_Int i;
|
||||
FT_Long w, h;
|
||||
@ -2084,8 +2123,8 @@
|
||||
|
||||
if ( w == FT_PIX_ROUND( bsize->x_ppem ) || ignore_width )
|
||||
{
|
||||
if ( index )
|
||||
*index = (FT_ULong)i;
|
||||
if ( size_index )
|
||||
*size_index = (FT_ULong)i;
|
||||
|
||||
return FT_Err_Ok;
|
||||
}
|
||||
@ -2544,6 +2583,9 @@
|
||||
if ( !face )
|
||||
return FT_Err_Invalid_Face_Handle;
|
||||
|
||||
if ( encoding == FT_ENCODING_NONE )
|
||||
return FT_Err_Invalid_Argument;
|
||||
|
||||
/* FT_ENCODING_UNICODE is special. We try to find the `best' Unicode */
|
||||
/* charmap available, i.e., one with UCS-4 characters, if possible. */
|
||||
/* */
|
||||
@ -3718,10 +3760,38 @@
|
||||
if ( library->generic.finalizer )
|
||||
library->generic.finalizer( library );
|
||||
|
||||
/* Close all modules in the library */
|
||||
/* Close all faces in the library. If we don't do
|
||||
* this, we can have some subtle memory leaks.
|
||||
* Example:
|
||||
*
|
||||
* - the cff font driver uses the pshinter module in cff_size_done
|
||||
* - if the pshinter module is destroyed before the cff font driver,
|
||||
* opened FT_Face objects managed by the driver are not properly
|
||||
* destroyed, resulting in a memory leak
|
||||
*/
|
||||
{
|
||||
FT_UInt n;
|
||||
|
||||
|
||||
for ( n = 0; n < library->num_modules; n++ )
|
||||
{
|
||||
FT_Module module = library->modules[n];
|
||||
FT_List faces;
|
||||
|
||||
|
||||
if ( ( module->clazz->module_flags & FT_MODULE_FONT_DRIVER ) == 0 )
|
||||
continue;
|
||||
|
||||
faces = &FT_DRIVER(module)->faces_list;
|
||||
while ( faces->head )
|
||||
FT_Done_Face( FT_FACE( faces->head->data ) );
|
||||
}
|
||||
}
|
||||
|
||||
/* Close all other modules in the library */
|
||||
#if 1
|
||||
/* XXX Modules are removed in the reversed order so that */
|
||||
/* type42 module is removed before truetype module. This */
|
||||
/* type42 module is removed before truetype module. This */
|
||||
/* avoids double free in some occasions. It is a hack. */
|
||||
while ( library->num_modules > 0 )
|
||||
FT_Remove_Module( library,
|
||||
@ -3861,7 +3931,7 @@
|
||||
|
||||
#endif /* FT_CONFIG_OPTION_OLD_INTERNALS */
|
||||
|
||||
|
||||
|
||||
FT_EXPORT_DEF( FT_Error )
|
||||
FT_Get_SubGlyph_Info( FT_GlyphSlot glyph,
|
||||
FT_UInt sub_index,
|
||||
@ -3872,14 +3942,14 @@
|
||||
FT_Matrix *p_transform )
|
||||
{
|
||||
FT_Error error = FT_Err_Invalid_Argument;
|
||||
|
||||
|
||||
if ( glyph != NULL &&
|
||||
|
||||
if ( glyph != NULL &&
|
||||
glyph->format == FT_GLYPH_FORMAT_COMPOSITE &&
|
||||
sub_index < glyph->num_subglyphs )
|
||||
{
|
||||
FT_SubGlyph subg = glyph->subglyphs + sub_index;
|
||||
|
||||
|
||||
|
||||
*p_index = subg->index;
|
||||
*p_flags = subg->flags;
|
||||
|
@ -4,7 +4,7 @@
|
||||
/* */
|
||||
/* FreeType API for validating OpenType tables (body). */
|
||||
/* */
|
||||
/* Copyright 2004 by */
|
||||
/* Copyright 2004, 2006 by */
|
||||
/* David Turner, Robert Wilhelm, and Werner Lemberg. */
|
||||
/* */
|
||||
/* This file is part of the FreeType project, and may only be used, */
|
||||
@ -62,7 +62,7 @@
|
||||
GSUB_table,
|
||||
JSTF_table );
|
||||
else
|
||||
error = FT_Err_Invalid_Argument;
|
||||
error = FT_Err_Unimplemented_Feature;
|
||||
|
||||
Exit:
|
||||
return error;
|
||||
|
@ -4,7 +4,7 @@
|
||||
/* */
|
||||
/* FreeType outline management (body). */
|
||||
/* */
|
||||
/* Copyright 1996-2001, 2002, 2003, 2004, 2005, 2006 by */
|
||||
/* Copyright 1996-2001, 2002, 2003, 2004, 2005, 2006, 2007 by */
|
||||
/* David Turner, Robert Wilhelm, and Werner Lemberg. */
|
||||
/* */
|
||||
/* This file is part of the FreeType project, and may only be used, */
|
||||
@ -732,7 +732,7 @@
|
||||
return ( n % 2 );
|
||||
}
|
||||
|
||||
|
||||
|
||||
static FT_Bool
|
||||
ft_contour_enclosed( FT_Outline* outline,
|
||||
FT_UShort c )
|
||||
@ -934,7 +934,8 @@
|
||||
FT_Outline_Get_Orientation( FT_Outline* outline )
|
||||
{
|
||||
FT_Pos xmin = 32768L;
|
||||
FT_Vector* xmin_point = NULL;
|
||||
FT_Pos xmin_ymin = 32768L;
|
||||
FT_Pos xmin_ymax = -32768L;
|
||||
FT_Vector* xmin_first = NULL;
|
||||
FT_Vector* xmin_last = NULL;
|
||||
|
||||
@ -943,22 +944,31 @@
|
||||
FT_Vector* first;
|
||||
FT_Vector* last;
|
||||
FT_Vector* prev;
|
||||
FT_Vector* next;
|
||||
FT_Vector* point;
|
||||
|
||||
int i;
|
||||
FT_Pos ray_y[3];
|
||||
FT_Orientation result[3];
|
||||
|
||||
|
||||
if ( !outline || outline->n_points <= 0 )
|
||||
return FT_ORIENTATION_TRUETYPE;
|
||||
|
||||
/* We use the nonzero winding rule to find the orientation. */
|
||||
/* Since glyph outlines behave much more `regular' than arbitrary */
|
||||
/* cubic or quadratic curves, this test deals with the polygon */
|
||||
/* only which is spanned up by the control points. */
|
||||
|
||||
first = outline->points;
|
||||
for ( contour = outline->contours;
|
||||
contour < outline->contours + outline->n_contours;
|
||||
contour++, first = last + 1 )
|
||||
{
|
||||
FT_Vector* point;
|
||||
FT_Int on_curve;
|
||||
FT_Int on_curve_count = 0;
|
||||
FT_Pos tmp_xmin = 32768L;
|
||||
FT_Vector* tmp_xmin_point = NULL;
|
||||
FT_Pos contour_xmin = 32768L;
|
||||
FT_Pos contour_xmax = -32768L;
|
||||
FT_Pos contour_ymin = 32768L;
|
||||
FT_Pos contour_ymax = -32768L;
|
||||
|
||||
|
||||
last = outline->points + *contour;
|
||||
|
||||
@ -968,55 +978,108 @@
|
||||
|
||||
for ( point = first; point <= last; ++point )
|
||||
{
|
||||
/* Count on-curve points. If there are less than 3 on-curve */
|
||||
/* points, just bypass this contour. */
|
||||
on_curve = outline->tags[point - outline->points] & 1;
|
||||
on_curve_count += on_curve;
|
||||
if ( point->x < contour_xmin )
|
||||
contour_xmin = point->x;
|
||||
|
||||
if ( point->x < tmp_xmin && on_curve )
|
||||
{
|
||||
tmp_xmin = point->x;
|
||||
tmp_xmin_point = point;
|
||||
}
|
||||
if ( point->x > contour_xmax )
|
||||
contour_xmax = point->x;
|
||||
|
||||
if ( point->y < contour_ymin )
|
||||
contour_ymin = point->y;
|
||||
|
||||
if ( point->y > contour_ymax )
|
||||
contour_ymax = point->y;
|
||||
}
|
||||
|
||||
if ( on_curve_count > 2 && tmp_xmin < xmin )
|
||||
if ( contour_xmin < xmin &&
|
||||
contour_xmin != contour_xmax &&
|
||||
contour_ymin != contour_ymax )
|
||||
{
|
||||
xmin = tmp_xmin;
|
||||
xmin_point = tmp_xmin_point;
|
||||
xmin = contour_xmin;
|
||||
xmin_ymin = contour_ymin;
|
||||
xmin_ymax = contour_ymax;
|
||||
xmin_first = first;
|
||||
xmin_last = last;
|
||||
}
|
||||
}
|
||||
|
||||
if ( !xmin_point )
|
||||
if ( xmin == 32768 )
|
||||
return FT_ORIENTATION_TRUETYPE;
|
||||
|
||||
prev = ( xmin_point == xmin_first ) ? xmin_last : xmin_point - 1;
|
||||
next = ( xmin_point == xmin_last ) ? xmin_first : xmin_point + 1;
|
||||
ray_y[0] = ( xmin_ymin * 3 + xmin_ymax ) >> 2;
|
||||
ray_y[1] = ( xmin_ymin + xmin_ymax ) >> 1;
|
||||
ray_y[2] = ( xmin_ymin + xmin_ymax * 3 ) >> 2;
|
||||
|
||||
/* Skip off-curve points */
|
||||
while ( ( outline->tags[prev - outline->points] & 1 ) == 0 )
|
||||
for ( i = 0; i < 3; i++ )
|
||||
{
|
||||
if ( prev == xmin_first )
|
||||
prev = xmin_last;
|
||||
else
|
||||
--prev;
|
||||
FT_Pos left_x;
|
||||
FT_Pos right_x;
|
||||
FT_Vector* left1;
|
||||
FT_Vector* left2;
|
||||
FT_Vector* right1;
|
||||
FT_Vector* right2;
|
||||
|
||||
|
||||
RedoRay:
|
||||
left_x = 32768L;
|
||||
right_x = -32768L;
|
||||
|
||||
left1 = left2 = right1 = right2 = NULL;
|
||||
|
||||
prev = xmin_last;
|
||||
for ( point = xmin_first; point <= xmin_last; prev = point, ++point )
|
||||
{
|
||||
FT_Pos tmp_x;
|
||||
|
||||
|
||||
if ( point->y == ray_y[i] || prev->y == ray_y[i] )
|
||||
{
|
||||
ray_y[i]++;
|
||||
goto RedoRay;
|
||||
}
|
||||
|
||||
if ( ( point->y < ray_y[i] && prev->y < ray_y[i] ) ||
|
||||
( point->y > ray_y[i] && prev->y > ray_y[i] ) )
|
||||
continue;
|
||||
|
||||
tmp_x = FT_MulDiv( point->x - prev->x,
|
||||
ray_y[i] - prev->y,
|
||||
point->y - prev->y ) + prev->x;
|
||||
|
||||
if ( tmp_x < left_x )
|
||||
{
|
||||
left_x = tmp_x;
|
||||
left1 = prev;
|
||||
left2 = point;
|
||||
}
|
||||
|
||||
if ( tmp_x > right_x )
|
||||
{
|
||||
right_x = tmp_x;
|
||||
right1 = prev;
|
||||
right2 = point;
|
||||
}
|
||||
}
|
||||
|
||||
if ( left1 && right1 )
|
||||
{
|
||||
if ( left1->y < left2->y && right1->y > right2->y )
|
||||
result[i] = FT_ORIENTATION_TRUETYPE;
|
||||
else if ( left1->y > left2->y && right1->y < right2->y )
|
||||
result[i] = FT_ORIENTATION_POSTSCRIPT;
|
||||
else
|
||||
result[i] = FT_ORIENTATION_NONE;
|
||||
}
|
||||
}
|
||||
|
||||
while ( ( outline->tags[next - outline->points] & 1 ) == 0 )
|
||||
{
|
||||
if ( next == xmin_last )
|
||||
next = xmin_first;
|
||||
else
|
||||
++next;
|
||||
}
|
||||
if ( result[0] != FT_ORIENTATION_NONE &&
|
||||
( result[0] == result[1] || result[0] == result[2] ) )
|
||||
return result[0];
|
||||
|
||||
if ( FT_Atan2( prev->x - xmin_point->x, prev->y - xmin_point->y ) >
|
||||
FT_Atan2( next->x - xmin_point->x, next->y - xmin_point->y ) )
|
||||
return FT_ORIENTATION_POSTSCRIPT;
|
||||
else
|
||||
return FT_ORIENTATION_TRUETYPE;
|
||||
if ( result[1] != FT_ORIENTATION_NONE && result[1] == result[2] )
|
||||
return result[1];
|
||||
|
||||
return FT_ORIENTATION_TRUETYPE;
|
||||
}
|
||||
|
||||
|
||||
|
@ -647,7 +647,7 @@
|
||||
error = raccess_guess_apple_double( library, stream2, file_name,
|
||||
&nouse, result_offset );
|
||||
|
||||
FT_Stream_Close( stream2 );
|
||||
FT_Stream_Free( stream2, 0 );
|
||||
|
||||
return error;
|
||||
}
|
||||
|
@ -137,8 +137,11 @@
|
||||
return;
|
||||
}
|
||||
|
||||
/* assume the layout is horizontal */
|
||||
slot->advance.x += xstr;
|
||||
if ( slot->advance.x )
|
||||
slot->advance.x += xstr;
|
||||
|
||||
if ( slot->advance.y )
|
||||
slot->advance.y += ystr;
|
||||
|
||||
slot->metrics.width += xstr;
|
||||
slot->metrics.height += ystr;
|
||||
|
@ -120,12 +120,16 @@
|
||||
FT_Error error = FT_Err_Ok;
|
||||
|
||||
|
||||
if ( cur_count < 0 || new_count < 0 || item_size <= 0 )
|
||||
/* Note that we now accept `item_size == 0' as a valid parameter, in
|
||||
* order to cover very weird cases where an ALLOC_MULT macro would be
|
||||
* called.
|
||||
*/
|
||||
if ( cur_count < 0 || new_count < 0 || item_size < 0 )
|
||||
{
|
||||
/* may help catch/prevent nasty security issues */
|
||||
error = FT_Err_Invalid_Argument;
|
||||
}
|
||||
else if ( new_count == 0 )
|
||||
else if ( new_count == 0 || item_size == 0 )
|
||||
{
|
||||
ft_mem_free( memory, block );
|
||||
block = NULL;
|
||||
|
@ -3,7 +3,7 @@
|
||||
#
|
||||
|
||||
|
||||
# Copyright 1996-2000, 2002, 2003, 2004, 2005, 2006 by
|
||||
# Copyright 1996-2000, 2002, 2003, 2004, 2005, 2006, 2007 by
|
||||
# David Turner, Robert Wilhelm, and Werner Lemberg.
|
||||
#
|
||||
# This file is part of the FreeType project, and may only be used, modified,
|
||||
@ -32,8 +32,10 @@ BASE_COMPILE := $(FT_COMPILE) $I$(subst /,$(COMPILER_SEP),$(SRC_DIR)/base)
|
||||
#
|
||||
# ftsystem, ftinit, and ftdebug are handled by freetype.mk
|
||||
#
|
||||
BASE_SRC := $(BASE_DIR)/ftapi.c \
|
||||
$(BASE_DIR)/ftcalc.c \
|
||||
# All files listed here should be included in `ftbase.c' (for a `single'
|
||||
# build).
|
||||
#
|
||||
BASE_SRC := $(BASE_DIR)/ftcalc.c \
|
||||
$(BASE_DIR)/ftdbgmem.c \
|
||||
$(BASE_DIR)/ftgloadr.c \
|
||||
$(BASE_DIR)/ftnames.c \
|
||||
|
@ -8,14 +8,14 @@ Introduction
|
||||
************
|
||||
|
||||
BDF (Bitmap Distribution Format) is a bitmap font format defined by Adobe,
|
||||
which is intended to be easily understood by both humans and computers.
|
||||
which is intended to be easily understood by both humans and computers.
|
||||
This code implements a BDF driver for the FreeType library, following the
|
||||
Adobe Specification V 2.2. The specification of the BDF font format is
|
||||
available from Adobe's web site:
|
||||
|
||||
http://partners.adobe.com/asn/developer/PDFS/TN/5005.BDF_Spec.pdf
|
||||
|
||||
Many good bitmap fonts in bdf format come with XFree86 (www.XFree86.org).
|
||||
Many good bitmap fonts in bdf format come with XFree86 (www.XFree86.org).
|
||||
They do not define vertical metrics, because the X Consortium BDF
|
||||
specification has removed them.
|
||||
|
||||
@ -40,13 +40,13 @@ client application the work of interpreting them. For instance:
|
||||
FT_New_Face( library, ..., &face );
|
||||
|
||||
bdfface = (BDF_Public_Face)face;
|
||||
|
||||
if ( ( bdfface->charset_registry == "ISO10646" ) &&
|
||||
|
||||
if ( ( bdfface->charset_registry == "ISO10646" ) &&
|
||||
( bdfface->charset_encoding == "1" ) )
|
||||
[..]
|
||||
|
||||
|
||||
Thus the driver always exports `ft_encoding_none' as face->charmap.encoding.
|
||||
Thus the driver always exports `ft_encoding_none' as face->charmap.encoding.
|
||||
FT_Get_Char_Index's behavior is unmodified, that is, it converts the ULong
|
||||
value given as argument into the corresponding glyph number.
|
||||
|
||||
|
@ -3,7 +3,7 @@
|
||||
FreeType font driver for bdf files
|
||||
|
||||
Copyright (C) 2001, 2002 by
|
||||
Francesco Zappa Nardelli
|
||||
Francesco Zappa Nardelli
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
|
@ -161,7 +161,7 @@ FT_BEGIN_HEADER
|
||||
{
|
||||
const char* key;
|
||||
void* data;
|
||||
|
||||
|
||||
} _hashnode, *hashnode;
|
||||
|
||||
|
||||
|
@ -435,6 +435,8 @@ THE SOFTWARE.
|
||||
/* convert from 722.7 decipoints to 72 points per inch */
|
||||
bsize->size =
|
||||
(FT_Pos)( ( prop->value.int32 * 64 * 7200 + 36135L ) / 72270L );
|
||||
else
|
||||
bsize->size = bsize->width << 6;
|
||||
|
||||
prop = bdf_get_font_property( font, "PIXEL_SIZE" );
|
||||
if ( prop )
|
||||
@ -646,16 +648,17 @@ THE SOFTWARE.
|
||||
FT_UInt glyph_index,
|
||||
FT_Int32 load_flags )
|
||||
{
|
||||
BDF_Face face = (BDF_Face)FT_SIZE_FACE( size );
|
||||
BDF_Face bdf = (BDF_Face)FT_SIZE_FACE( size );
|
||||
FT_Face face = FT_FACE( bdf );
|
||||
FT_Error error = BDF_Err_Ok;
|
||||
FT_Bitmap* bitmap = &slot->bitmap;
|
||||
bdf_glyph_t glyph;
|
||||
int bpp = face->bdffont->bpp;
|
||||
int bpp = bdf->bdffont->bpp;
|
||||
|
||||
FT_UNUSED( load_flags );
|
||||
|
||||
|
||||
if ( !face )
|
||||
if ( !face || glyph_index >= (FT_UInt)face->num_glyphs )
|
||||
{
|
||||
error = BDF_Err_Invalid_Argument;
|
||||
goto Exit;
|
||||
@ -663,12 +666,12 @@ THE SOFTWARE.
|
||||
|
||||
/* index 0 is the undefined glyph */
|
||||
if ( glyph_index == 0 )
|
||||
glyph_index = face->default_glyph;
|
||||
glyph_index = bdf->default_glyph;
|
||||
else
|
||||
glyph_index--;
|
||||
|
||||
/* slot, bitmap => freetype, glyph => bdflib */
|
||||
glyph = face->bdffont->glyphs[glyph_index];
|
||||
glyph = bdf->bdffont->glyphs[glyph_index];
|
||||
|
||||
bitmap->rows = glyph.bbx.height;
|
||||
bitmap->width = glyph.bbx.width;
|
||||
@ -710,7 +713,7 @@ THE SOFTWARE.
|
||||
* used here, provided such fonts do exist.
|
||||
*/
|
||||
ft_synthesize_vertical_metrics( &slot->metrics,
|
||||
face->bdffont->bbx.height << 6 );
|
||||
bdf->bdffont->bbx.height << 6 );
|
||||
|
||||
Exit:
|
||||
return error;
|
||||
|
@ -2204,7 +2204,7 @@
|
||||
bdf_options_t* opts,
|
||||
bdf_font_t* *font )
|
||||
{
|
||||
unsigned long lineno;
|
||||
unsigned long lineno = 0; /* make compiler happy */
|
||||
_bdf_parse_t *p;
|
||||
|
||||
FT_Memory memory = extmemory;
|
||||
@ -2224,7 +2224,7 @@
|
||||
error = _bdf_readstream( stream, _bdf_parse_start,
|
||||
(void *)p, &lineno );
|
||||
if ( error )
|
||||
goto Exit;
|
||||
goto Fail;
|
||||
|
||||
if ( p->font != 0 )
|
||||
{
|
||||
@ -2316,7 +2316,7 @@
|
||||
if ( FT_RENEW_ARRAY( p->font->comments,
|
||||
p->font->comments_len,
|
||||
p->font->comments_len + 1 ) )
|
||||
goto Exit;
|
||||
goto Fail;
|
||||
|
||||
p->font->comments[p->font->comments_len] = 0;
|
||||
}
|
||||
@ -2337,6 +2337,15 @@
|
||||
}
|
||||
|
||||
return error;
|
||||
|
||||
Fail:
|
||||
bdf_free_font( p->font );
|
||||
|
||||
memory = extmemory;
|
||||
|
||||
FT_FREE( p->font );
|
||||
|
||||
goto Exit;
|
||||
}
|
||||
|
||||
|
||||
|
@ -4,7 +4,7 @@
|
||||
|
||||
# Copyright 2001, 2002, 2006 by
|
||||
# Francesco Zappa Nardelli
|
||||
#
|
||||
#
|
||||
# Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
# of this software and associated documentation files (the "Software"), to deal
|
||||
# in the Software without restriction, including without limitation the rights
|
||||
|
8
src/libs/freetype2/cache/ftccmap.c
vendored
8
src/libs/freetype2/cache/ftccmap.c
vendored
@ -305,9 +305,13 @@
|
||||
* more than a few charmaps, so if the index is very large...
|
||||
*
|
||||
* It is also very unlikely that a rogue client is interested
|
||||
* in Unicode values 0 to 3.
|
||||
* in Unicode values 0 to 15.
|
||||
*
|
||||
* NOTE: The original threshold was 4, but we found a font from the
|
||||
* Adobe Acrobat Reader Pack, named `KozMinProVI-Regular.otf',
|
||||
* which contains more than 5 charmaps.
|
||||
*/
|
||||
if ( cmap_index >= 4 )
|
||||
if ( cmap_index >= 16 )
|
||||
{
|
||||
FTC_OldCMapDesc desc = (FTC_OldCMapDesc) face_id;
|
||||
|
||||
|
@ -120,9 +120,10 @@
|
||||
/*************************************************************************/
|
||||
|
||||
FT_CALLBACK_DEF( const char* )
|
||||
cff_sid_to_glyph_name( CFF_Font cff,
|
||||
cff_sid_to_glyph_name( TT_Face face,
|
||||
FT_UInt idx )
|
||||
{
|
||||
CFF_Font cff = (CFF_Font)face->extra.data;
|
||||
CFF_Charset charset = &cff->charset;
|
||||
FT_Service_PsCMaps psnames = (FT_Service_PsCMaps)cff->psnames;
|
||||
FT_UInt sid = charset->sids[idx];
|
||||
@ -132,6 +133,17 @@
|
||||
}
|
||||
|
||||
|
||||
FT_CALLBACK_DEF( void )
|
||||
cff_sid_free_glyph_name( TT_Face face,
|
||||
const char* gname )
|
||||
{
|
||||
FT_Memory memory = FT_FACE_MEMORY( face );
|
||||
|
||||
|
||||
FT_FREE( gname );
|
||||
}
|
||||
|
||||
|
||||
FT_CALLBACK_DEF( FT_Error )
|
||||
cff_cmap_unicode_init( PS_Unicodes unicodes )
|
||||
{
|
||||
@ -149,8 +161,9 @@
|
||||
return psnames->unicodes_init( memory,
|
||||
unicodes,
|
||||
cff->num_glyphs,
|
||||
(PS_Glyph_NameFunc)&cff_sid_to_glyph_name,
|
||||
(FT_Pointer)cff );
|
||||
(PS_GetGlyphNameFunc)&cff_sid_to_glyph_name,
|
||||
(PS_FreeGlyphNameFunc)&cff_sid_free_glyph_name,
|
||||
(FT_Pointer)face );
|
||||
}
|
||||
|
||||
|
||||
|
@ -39,14 +39,14 @@ FT_BEGIN_HEADER
|
||||
{
|
||||
FT_CMapRec cmap;
|
||||
FT_UShort* gids; /* up to 256 elements */
|
||||
|
||||
|
||||
} CFF_CMapStdRec;
|
||||
|
||||
|
||||
FT_CALLBACK_TABLE const FT_CMap_ClassRec
|
||||
cff_cmap_encoding_class_rec;
|
||||
|
||||
|
||||
|
||||
/*************************************************************************/
|
||||
/*************************************************************************/
|
||||
/***** *****/
|
||||
|
@ -4,7 +4,7 @@
|
||||
/* */
|
||||
/* OpenType font driver implementation (body). */
|
||||
/* */
|
||||
/* Copyright 1996-2001, 2002, 2003, 2004, 2005, 2006 by */
|
||||
/* Copyright 1996-2001, 2002, 2003, 2004, 2005, 2006, 2007 by */
|
||||
/* David Turner, Robert Wilhelm, and Werner Lemberg. */
|
||||
/* */
|
||||
/* This file is part of the FreeType project, and may only be used, */
|
||||
@ -302,9 +302,57 @@
|
||||
}
|
||||
|
||||
|
||||
static FT_Error
|
||||
cff_ps_get_font_info( CFF_Face face,
|
||||
PS_FontInfoRec* afont_info )
|
||||
{
|
||||
CFF_Font cff = (CFF_Font)face->extra.data;
|
||||
FT_Error error = FT_Err_Ok;
|
||||
|
||||
|
||||
if ( cff && cff->font_info == NULL )
|
||||
{
|
||||
CFF_FontRecDict dict = &cff->top_font.font_dict;
|
||||
PS_FontInfoRec *font_info;
|
||||
FT_Memory memory = face->root.memory;
|
||||
|
||||
|
||||
if ( FT_ALLOC( font_info, sizeof ( *font_info ) ) )
|
||||
goto Fail;
|
||||
|
||||
font_info->version = cff_index_get_sid_string( &cff->string_index,
|
||||
dict->version,
|
||||
cff->psnames );
|
||||
font_info->notice = cff_index_get_sid_string( &cff->string_index,
|
||||
dict->notice,
|
||||
cff->psnames );
|
||||
font_info->full_name = cff_index_get_sid_string( &cff->string_index,
|
||||
dict->full_name,
|
||||
cff->psnames );
|
||||
font_info->family_name = cff_index_get_sid_string( &cff->string_index,
|
||||
dict->family_name,
|
||||
cff->psnames );
|
||||
font_info->weight = cff_index_get_sid_string( &cff->string_index,
|
||||
dict->weight,
|
||||
cff->psnames );
|
||||
font_info->italic_angle = dict->italic_angle;
|
||||
font_info->is_fixed_pitch = dict->is_fixed_pitch;
|
||||
font_info->underline_position = (FT_Short)dict->underline_position;
|
||||
font_info->underline_thickness = (FT_Short)dict->underline_thickness;
|
||||
|
||||
cff->font_info = font_info;
|
||||
}
|
||||
|
||||
*afont_info = *cff->font_info;
|
||||
|
||||
Fail:
|
||||
return error;
|
||||
}
|
||||
|
||||
|
||||
static const FT_Service_PsInfoRec cff_service_ps_info =
|
||||
{
|
||||
(PS_GetFontInfoFunc) NULL, /* unsupported with CFF fonts */
|
||||
(PS_GetFontInfoFunc) cff_ps_get_font_info,
|
||||
(PS_HasGlyphNamesFunc) cff_ps_has_glyph_names,
|
||||
(PS_GetFontPrivateFunc)NULL /* unsupported with CFF fonts */
|
||||
};
|
||||
|
@ -4,7 +4,7 @@
|
||||
/* */
|
||||
/* OpenType Glyph Loader (body). */
|
||||
/* */
|
||||
/* Copyright 1996-2001, 2002, 2003, 2004, 2005, 2006 by */
|
||||
/* Copyright 1996-2001, 2002, 2003, 2004, 2005, 2006, 2007 by */
|
||||
/* David Turner, Robert Wilhelm, and Werner Lemberg. */
|
||||
/* */
|
||||
/* This file is part of the FreeType project, and may only be used, */
|
||||
@ -2275,16 +2275,29 @@
|
||||
FT_UInt glyph_index,
|
||||
FT_Int32 load_flags )
|
||||
{
|
||||
FT_Error error;
|
||||
CFF_Decoder decoder;
|
||||
TT_Face face = (TT_Face)glyph->root.face;
|
||||
FT_Bool hinting;
|
||||
CFF_Font cff = (CFF_Font)face->extra.data;
|
||||
FT_Error error;
|
||||
CFF_Decoder decoder;
|
||||
TT_Face face = (TT_Face)glyph->root.face;
|
||||
FT_Bool hinting;
|
||||
CFF_Font cff = (CFF_Font)face->extra.data;
|
||||
|
||||
FT_Matrix font_matrix;
|
||||
FT_Vector font_offset;
|
||||
FT_Matrix font_matrix;
|
||||
FT_Vector font_offset;
|
||||
|
||||
|
||||
/* in a CID-keyed font, consider `glyph_index' as a CID and map */
|
||||
/* it immediately to the real glyph_index -- if it isn't a */
|
||||
/* subsetted font, glyph_indices and CIDs are identical, though */
|
||||
if ( cff->top_font.font_dict.cid_registry != 0xFFFFU &&
|
||||
cff->charset.cids )
|
||||
{
|
||||
glyph_index = cff_charset_cid_to_gindex( &cff->charset, glyph_index );
|
||||
if ( glyph_index == 0 )
|
||||
return CFF_Err_Invalid_Argument;
|
||||
}
|
||||
else if ( glyph_index >= cff->num_glyphs )
|
||||
return CFF_Err_Invalid_Argument;
|
||||
|
||||
if ( load_flags & FT_LOAD_NO_RECURSE )
|
||||
load_flags |= FT_LOAD_NO_SCALE | FT_LOAD_NO_HINTING;
|
||||
|
||||
@ -2376,18 +2389,6 @@
|
||||
FT_ULong charstring_len;
|
||||
|
||||
|
||||
/* in a CID-keyed font, consider `glyph_index' as a CID and map */
|
||||
/* it immediately to the real glyph_index -- if it isn't a */
|
||||
/* subsetted font, glyph_indices and CIDs are identical, though */
|
||||
if ( cff->top_font.font_dict.cid_registry != 0xFFFFU &&
|
||||
cff->charset.cids )
|
||||
{
|
||||
if ( glyph_index < cff->charset.max_cid )
|
||||
glyph_index = cff->charset.cids[glyph_index];
|
||||
else
|
||||
glyph_index = 0;
|
||||
}
|
||||
|
||||
cff_decoder_init( &decoder, face, size, glyph, hinting,
|
||||
FT_LOAD_TARGET_MODE( load_flags ) );
|
||||
|
||||
@ -2421,13 +2422,15 @@
|
||||
/* See how charstring loads at cff_index_access_element() in */
|
||||
/* cffload.c. */
|
||||
{
|
||||
CFF_IndexRec csindex = cff->charstrings_index;
|
||||
CFF_Index csindex = &cff->charstrings_index;
|
||||
|
||||
|
||||
glyph->root.control_data =
|
||||
csindex.bytes + csindex.offsets[glyph_index] - 1;
|
||||
glyph->root.control_len =
|
||||
charstring_len;
|
||||
if ( csindex->offsets )
|
||||
{
|
||||
glyph->root.control_data = csindex->bytes +
|
||||
csindex->offsets[glyph_index] - 1;
|
||||
glyph->root.control_len = charstring_len;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -4,7 +4,7 @@
|
||||
/* */
|
||||
/* OpenType & CFF data/program tables loader (specification). */
|
||||
/* */
|
||||
/* Copyright 1996-2001, 2002, 2003 by */
|
||||
/* Copyright 1996-2001, 2002, 2003, 2007 by */
|
||||
/* David Turner, Robert Wilhelm, and Werner Lemberg. */
|
||||
/* */
|
||||
/* This file is part of the FreeType project, and may only be used, */
|
||||
@ -52,6 +52,11 @@ FT_BEGIN_HEADER
|
||||
FT_Byte** pbytes );
|
||||
|
||||
|
||||
FT_LOCAL( FT_UInt )
|
||||
cff_charset_cid_to_gindex( CFF_Charset charset,
|
||||
FT_UInt cid );
|
||||
|
||||
|
||||
FT_LOCAL( FT_Error )
|
||||
cff_font_load( FT_Stream stream,
|
||||
FT_Int face_index,
|
||||
|
@ -4,7 +4,7 @@
|
||||
/* */
|
||||
/* OpenType objects manager (body). */
|
||||
/* */
|
||||
/* Copyright 1996-2001, 2002, 2003, 2004, 2005, 2006 by */
|
||||
/* Copyright 1996-2001, 2002, 2003, 2004, 2005, 2006, 2007 by */
|
||||
/* David Turner, Robert Wilhelm, and Werner Lemberg. */
|
||||
/* */
|
||||
/* This file is part of the FreeType project, and may only be used, */
|
||||
@ -207,13 +207,13 @@
|
||||
{
|
||||
CFF_Face cffface = (CFF_Face)size->face;
|
||||
SFNT_Service sfnt = (SFNT_Service)cffface->sfnt;
|
||||
FT_ULong index;
|
||||
FT_ULong strike_index;
|
||||
|
||||
|
||||
if ( sfnt->set_sbit_strike( cffface, req, &index ) )
|
||||
if ( sfnt->set_sbit_strike( cffface, req, &strike_index ) )
|
||||
cffsize->strike_index = 0xFFFFFFFFUL;
|
||||
else
|
||||
return cff_size_select( size, index );
|
||||
return cff_size_select( size, strike_index );
|
||||
}
|
||||
|
||||
#endif /* TT_CONFIG_OPTION_EMBEDDED_BITMAPS */
|
||||
|
@ -4,7 +4,7 @@
|
||||
/* */
|
||||
/* OpenType objects manager (specification). */
|
||||
/* */
|
||||
/* Copyright 1996-2001, 2002, 2003, 2004, 2006 by */
|
||||
/* Copyright 1996-2001, 2002, 2003, 2004, 2006, 2007 by */
|
||||
/* David Turner, Robert Wilhelm, and Werner Lemberg. */
|
||||
/* */
|
||||
/* This file is part of the FreeType project, and may only be used, */
|
||||
@ -120,7 +120,7 @@ FT_BEGIN_HEADER
|
||||
|
||||
FT_LOCAL( FT_Error )
|
||||
cff_size_select( FT_Size size,
|
||||
FT_ULong index );
|
||||
FT_ULong strike_index );
|
||||
|
||||
#endif
|
||||
|
||||
|
@ -5,7 +5,7 @@
|
||||
/* Basic OpenType/CFF type definitions and interface (specification */
|
||||
/* only). */
|
||||
/* */
|
||||
/* Copyright 1996-2001, 2002, 2003, 2006 by */
|
||||
/* Copyright 1996-2001, 2002, 2003, 2006, 2007 by */
|
||||
/* David Turner, Robert Wilhelm, and Werner Lemberg. */
|
||||
/* */
|
||||
/* This file is part of the FreeType project, and may only be used, */
|
||||
@ -23,6 +23,7 @@
|
||||
|
||||
#include <ft2build.h>
|
||||
#include FT_FREETYPE_H
|
||||
#include FT_TYPE1_TABLES_H
|
||||
|
||||
|
||||
FT_BEGIN_HEADER
|
||||
@ -39,6 +40,9 @@ FT_BEGIN_HEADER
|
||||
/* <Fields> */
|
||||
/* stream :: The source input stream. */
|
||||
/* */
|
||||
/* start :: The position of the first index byte in the */
|
||||
/* input stream. */
|
||||
/* */
|
||||
/* count :: The number of elements in the index. */
|
||||
/* */
|
||||
/* off_size :: The size in bytes of object offsets in index. */
|
||||
@ -46,16 +50,21 @@ FT_BEGIN_HEADER
|
||||
/* data_offset :: The position of first data byte in the index's */
|
||||
/* bytes. */
|
||||
/* */
|
||||
/* offsets :: A table of element offsets in the index. */
|
||||
/* data_size :: The size of the data table in this index. */
|
||||
/* */
|
||||
/* offsets :: A table of element offsets in the index. Must be */
|
||||
/* loaded explicitly. */
|
||||
/* */
|
||||
/* bytes :: If the index is loaded in memory, its bytes. */
|
||||
/* */
|
||||
typedef struct CFF_IndexRec_
|
||||
{
|
||||
FT_Stream stream;
|
||||
FT_ULong start;
|
||||
FT_UInt count;
|
||||
FT_Byte off_size;
|
||||
FT_ULong data_offset;
|
||||
FT_ULong data_size;
|
||||
|
||||
FT_ULong* offsets;
|
||||
FT_Byte* bytes;
|
||||
@ -85,6 +94,8 @@ FT_BEGIN_HEADER
|
||||
FT_UShort* cids; /* the inverse mapping of `sids'; only needed */
|
||||
/* for CID-keyed fonts */
|
||||
FT_UInt max_cid;
|
||||
FT_UInt num_glyphs;
|
||||
|
||||
} CFF_CharsetRec, *CFF_Charset;
|
||||
|
||||
|
||||
@ -245,6 +256,9 @@ FT_BEGIN_HEADER
|
||||
/* interface to Postscript Names service */
|
||||
void* psnames;
|
||||
|
||||
/* since version 2.3.0 */
|
||||
PS_FontInfoRec* font_info; /* font info dictionary */
|
||||
|
||||
} CFF_FontRec, *CFF_Font;
|
||||
|
||||
|
||||
|
@ -230,6 +230,9 @@
|
||||
if ( error )
|
||||
return error;
|
||||
|
||||
/* TODO: initialize decoder.len_buildchar and decoder.buildchar */
|
||||
/* if we ever support CID-keyed multiple master fonts */
|
||||
|
||||
decoder.builder.metrics_only = 1;
|
||||
decoder.builder.load_points = 0;
|
||||
|
||||
@ -245,6 +248,8 @@
|
||||
|
||||
*max_advance = decoder.builder.advance.x;
|
||||
|
||||
psaux->t1_decoder_funcs->done( &decoder );
|
||||
|
||||
return CID_Err_Ok;
|
||||
}
|
||||
|
||||
@ -270,6 +275,12 @@
|
||||
FT_Vector font_offset;
|
||||
|
||||
|
||||
if ( glyph_index >= (FT_UInt)face->root.num_glyphs )
|
||||
{
|
||||
error = CID_Err_Invalid_Argument;
|
||||
goto Exit;
|
||||
}
|
||||
|
||||
if ( load_flags & FT_LOAD_NO_RECURSE )
|
||||
load_flags |= FT_LOAD_NO_SCALE | FT_LOAD_NO_HINTING;
|
||||
|
||||
@ -284,128 +295,132 @@
|
||||
|
||||
cidglyph->format = FT_GLYPH_FORMAT_OUTLINE;
|
||||
|
||||
{
|
||||
error = psaux->t1_decoder_funcs->init( &decoder,
|
||||
cidglyph->face,
|
||||
cidsize,
|
||||
cidglyph,
|
||||
0, /* glyph names -- XXX */
|
||||
0, /* blend == 0 */
|
||||
hinting,
|
||||
FT_LOAD_TARGET_MODE( load_flags ),
|
||||
cid_load_glyph );
|
||||
error = psaux->t1_decoder_funcs->init( &decoder,
|
||||
cidglyph->face,
|
||||
cidsize,
|
||||
cidglyph,
|
||||
0, /* glyph names -- XXX */
|
||||
0, /* blend == 0 */
|
||||
hinting,
|
||||
FT_LOAD_TARGET_MODE( load_flags ),
|
||||
cid_load_glyph );
|
||||
if ( error )
|
||||
goto Exit;
|
||||
|
||||
/* set up the decoder */
|
||||
decoder.builder.no_recurse = FT_BOOL(
|
||||
( ( load_flags & FT_LOAD_NO_RECURSE ) != 0 ) );
|
||||
/* TODO: initialize decoder.len_buildchar and decoder.buildchar */
|
||||
/* if we ever support CID-keyed multiple master fonts */
|
||||
|
||||
error = cid_load_glyph( &decoder, glyph_index );
|
||||
/* set up the decoder */
|
||||
decoder.builder.no_recurse = FT_BOOL(
|
||||
( ( load_flags & FT_LOAD_NO_RECURSE ) != 0 ) );
|
||||
|
||||
font_matrix = decoder.font_matrix;
|
||||
font_offset = decoder.font_offset;
|
||||
error = cid_load_glyph( &decoder, glyph_index );
|
||||
if ( error )
|
||||
goto Exit;
|
||||
|
||||
/* save new glyph tables */
|
||||
psaux->t1_decoder_funcs->done( &decoder );
|
||||
}
|
||||
font_matrix = decoder.font_matrix;
|
||||
font_offset = decoder.font_offset;
|
||||
|
||||
/* now, set the metrics -- this is rather simple, as */
|
||||
/* save new glyph tables */
|
||||
psaux->t1_decoder_funcs->done( &decoder );
|
||||
|
||||
/* now set the metrics -- this is rather simple, as */
|
||||
/* the left side bearing is the xMin, and the top side */
|
||||
/* bearing the yMax */
|
||||
if ( !error )
|
||||
cidglyph->outline.flags &= FT_OUTLINE_OWNER;
|
||||
cidglyph->outline.flags |= FT_OUTLINE_REVERSE_FILL;
|
||||
|
||||
/* for composite glyphs, return only left side bearing and */
|
||||
/* advance width */
|
||||
if ( load_flags & FT_LOAD_NO_RECURSE )
|
||||
{
|
||||
cidglyph->outline.flags &= FT_OUTLINE_OWNER;
|
||||
cidglyph->outline.flags |= FT_OUTLINE_REVERSE_FILL;
|
||||
FT_Slot_Internal internal = cidglyph->internal;
|
||||
|
||||
/* for composite glyphs, return only left side bearing and */
|
||||
/* advance width */
|
||||
if ( load_flags & FT_LOAD_NO_RECURSE )
|
||||
|
||||
cidglyph->metrics.horiBearingX = decoder.builder.left_bearing.x;
|
||||
cidglyph->metrics.horiAdvance = decoder.builder.advance.x;
|
||||
|
||||
internal->glyph_matrix = font_matrix;
|
||||
internal->glyph_delta = font_offset;
|
||||
internal->glyph_transformed = 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
FT_BBox cbox;
|
||||
FT_Glyph_Metrics* metrics = &cidglyph->metrics;
|
||||
FT_Vector advance;
|
||||
|
||||
|
||||
/* copy the _unscaled_ advance width */
|
||||
metrics->horiAdvance = decoder.builder.advance.x;
|
||||
cidglyph->linearHoriAdvance = decoder.builder.advance.x;
|
||||
cidglyph->internal->glyph_transformed = 0;
|
||||
|
||||
/* make up vertical ones */
|
||||
metrics->vertAdvance = ( face->cid.font_bbox.yMax -
|
||||
face->cid.font_bbox.yMin ) >> 16;
|
||||
cidglyph->linearVertAdvance = metrics->vertAdvance;
|
||||
|
||||
cidglyph->format = FT_GLYPH_FORMAT_OUTLINE;
|
||||
|
||||
if ( size && cidsize->metrics.y_ppem < 24 )
|
||||
cidglyph->outline.flags |= FT_OUTLINE_HIGH_PRECISION;
|
||||
|
||||
/* apply the font matrix */
|
||||
FT_Outline_Transform( &cidglyph->outline, &font_matrix );
|
||||
|
||||
FT_Outline_Translate( &cidglyph->outline,
|
||||
font_offset.x,
|
||||
font_offset.y );
|
||||
|
||||
advance.x = metrics->horiAdvance;
|
||||
advance.y = 0;
|
||||
FT_Vector_Transform( &advance, &font_matrix );
|
||||
metrics->horiAdvance = advance.x + font_offset.x;
|
||||
|
||||
advance.x = 0;
|
||||
advance.y = metrics->vertAdvance;
|
||||
FT_Vector_Transform( &advance, &font_matrix );
|
||||
metrics->vertAdvance = advance.y + font_offset.y;
|
||||
|
||||
if ( ( load_flags & FT_LOAD_NO_SCALE ) == 0 )
|
||||
{
|
||||
FT_Slot_Internal internal = cidglyph->internal;
|
||||
/* scale the outline and the metrics */
|
||||
FT_Int n;
|
||||
FT_Outline* cur = decoder.builder.base;
|
||||
FT_Vector* vec = cur->points;
|
||||
FT_Fixed x_scale = glyph->x_scale;
|
||||
FT_Fixed y_scale = glyph->y_scale;
|
||||
|
||||
|
||||
cidglyph->metrics.horiBearingX = decoder.builder.left_bearing.x;
|
||||
cidglyph->metrics.horiAdvance = decoder.builder.advance.x;
|
||||
/* First of all, scale the points */
|
||||
if ( !hinting || !decoder.builder.hints_funcs )
|
||||
for ( n = cur->n_points; n > 0; n--, vec++ )
|
||||
{
|
||||
vec->x = FT_MulFix( vec->x, x_scale );
|
||||
vec->y = FT_MulFix( vec->y, y_scale );
|
||||
}
|
||||
|
||||
internal->glyph_matrix = font_matrix;
|
||||
internal->glyph_delta = font_offset;
|
||||
internal->glyph_transformed = 1;
|
||||
/* Then scale the metrics */
|
||||
metrics->horiAdvance = FT_MulFix( metrics->horiAdvance, x_scale );
|
||||
metrics->vertAdvance = FT_MulFix( metrics->vertAdvance, y_scale );
|
||||
}
|
||||
else
|
||||
{
|
||||
FT_BBox cbox;
|
||||
FT_Glyph_Metrics* metrics = &cidglyph->metrics;
|
||||
FT_Vector advance;
|
||||
|
||||
/* compute the other metrics */
|
||||
FT_Outline_Get_CBox( &cidglyph->outline, &cbox );
|
||||
|
||||
/* copy the _unscaled_ advance width */
|
||||
metrics->horiAdvance = decoder.builder.advance.x;
|
||||
cidglyph->linearHoriAdvance = decoder.builder.advance.x;
|
||||
cidglyph->internal->glyph_transformed = 0;
|
||||
metrics->width = cbox.xMax - cbox.xMin;
|
||||
metrics->height = cbox.yMax - cbox.yMin;
|
||||
|
||||
/* make up vertical ones */
|
||||
metrics->vertAdvance = ( face->cid.font_bbox.yMax -
|
||||
face->cid.font_bbox.yMin ) >> 16;
|
||||
cidglyph->linearVertAdvance = metrics->vertAdvance;
|
||||
metrics->horiBearingX = cbox.xMin;
|
||||
metrics->horiBearingY = cbox.yMax;
|
||||
|
||||
cidglyph->format = FT_GLYPH_FORMAT_OUTLINE;
|
||||
|
||||
if ( size && cidsize->metrics.y_ppem < 24 )
|
||||
cidglyph->outline.flags |= FT_OUTLINE_HIGH_PRECISION;
|
||||
|
||||
/* apply the font matrix */
|
||||
FT_Outline_Transform( &cidglyph->outline, &font_matrix );
|
||||
|
||||
FT_Outline_Translate( &cidglyph->outline,
|
||||
font_offset.x,
|
||||
font_offset.y );
|
||||
|
||||
advance.x = metrics->horiAdvance;
|
||||
advance.y = 0;
|
||||
FT_Vector_Transform( &advance, &font_matrix );
|
||||
metrics->horiAdvance = advance.x + font_offset.x;
|
||||
advance.x = 0;
|
||||
advance.y = metrics->vertAdvance;
|
||||
FT_Vector_Transform( &advance, &font_matrix );
|
||||
metrics->vertAdvance = advance.y + font_offset.y;
|
||||
|
||||
if ( ( load_flags & FT_LOAD_NO_SCALE ) == 0 )
|
||||
{
|
||||
/* scale the outline and the metrics */
|
||||
FT_Int n;
|
||||
FT_Outline* cur = decoder.builder.base;
|
||||
FT_Vector* vec = cur->points;
|
||||
FT_Fixed x_scale = glyph->x_scale;
|
||||
FT_Fixed y_scale = glyph->y_scale;
|
||||
|
||||
|
||||
/* First of all, scale the points */
|
||||
if ( !hinting || !decoder.builder.hints_funcs )
|
||||
for ( n = cur->n_points; n > 0; n--, vec++ )
|
||||
{
|
||||
vec->x = FT_MulFix( vec->x, x_scale );
|
||||
vec->y = FT_MulFix( vec->y, y_scale );
|
||||
}
|
||||
|
||||
/* Then scale the metrics */
|
||||
metrics->horiAdvance = FT_MulFix( metrics->horiAdvance, x_scale );
|
||||
metrics->vertAdvance = FT_MulFix( metrics->vertAdvance, y_scale );
|
||||
}
|
||||
|
||||
/* compute the other metrics */
|
||||
FT_Outline_Get_CBox( &cidglyph->outline, &cbox );
|
||||
|
||||
metrics->width = cbox.xMax - cbox.xMin;
|
||||
metrics->height = cbox.yMax - cbox.yMin;
|
||||
|
||||
metrics->horiBearingX = cbox.xMin;
|
||||
metrics->horiBearingY = cbox.yMax;
|
||||
|
||||
/* make up vertical ones */
|
||||
ft_synthesize_vertical_metrics( metrics,
|
||||
metrics->vertAdvance );
|
||||
}
|
||||
/* make up vertical ones */
|
||||
ft_synthesize_vertical_metrics( metrics,
|
||||
metrics->vertAdvance );
|
||||
}
|
||||
|
||||
Exit:
|
||||
return error;
|
||||
}
|
||||
|
||||
|
@ -4,7 +4,7 @@
|
||||
/* */
|
||||
/* CID-keyed Type1 font loader (body). */
|
||||
/* */
|
||||
/* Copyright 1996-2001, 2002, 2003, 2004, 2005 by */
|
||||
/* Copyright 1996-2001, 2002, 2003, 2004, 2005, 2006 by */
|
||||
/* David Turner, Robert Wilhelm, and Werner Lemberg. */
|
||||
/* */
|
||||
/* This file is part of the FreeType project, and may only be used, */
|
||||
@ -240,10 +240,10 @@
|
||||
|
||||
#include "cidtoken.h"
|
||||
|
||||
T1_FIELD_CALLBACK( "FDArray", parse_fd_array )
|
||||
T1_FIELD_CALLBACK( "FontMatrix", parse_font_matrix )
|
||||
T1_FIELD_CALLBACK( "FDArray", parse_fd_array, 0 )
|
||||
T1_FIELD_CALLBACK( "FontMatrix", parse_font_matrix, 0 )
|
||||
|
||||
{ 0, T1_FIELD_LOCATION_CID_INFO, T1_FIELD_TYPE_NONE, 0, 0, 0, 0, 0 }
|
||||
{ 0, T1_FIELD_LOCATION_CID_INFO, T1_FIELD_TYPE_NONE, 0, 0, 0, 0, 0, 0 }
|
||||
};
|
||||
|
||||
|
||||
|
@ -4,7 +4,7 @@
|
||||
/* */
|
||||
/* CID-keyed Type1 parser (body). */
|
||||
/* */
|
||||
/* Copyright 1996-2001, 2002, 2003, 2004, 2005, 2006 by */
|
||||
/* Copyright 1996-2001, 2002, 2003, 2004, 2005, 2006, 2007 by */
|
||||
/* David Turner, Robert Wilhelm, and Werner Lemberg. */
|
||||
/* */
|
||||
/* This file is part of the FreeType project, and may only be used, */
|
||||
@ -83,7 +83,8 @@
|
||||
goto Exit;
|
||||
|
||||
Again:
|
||||
/* now, read the rest of the file until we find a `StartData' */
|
||||
/* now, read the rest of the file until we find */
|
||||
/* `StartData' or `/sfnts' */
|
||||
{
|
||||
FT_Byte buffer[256 + 10];
|
||||
FT_Int read_len = 256 + 10;
|
||||
@ -92,7 +93,7 @@
|
||||
|
||||
for ( offset = (FT_ULong)FT_STREAM_POS(); ; offset += 256 )
|
||||
{
|
||||
FT_Int stream_len;
|
||||
FT_Int stream_len;
|
||||
|
||||
|
||||
stream_len = stream->size - FT_STREAM_POS();
|
||||
@ -116,6 +117,11 @@
|
||||
offset += p - buffer + 10;
|
||||
goto Found;
|
||||
}
|
||||
else if ( p[1] == 's' && ft_strncmp( (char*)p, "/sfnts", 6 ) == 0 )
|
||||
{
|
||||
offset += p - buffer + 7;
|
||||
goto Found;
|
||||
}
|
||||
}
|
||||
|
||||
FT_MEM_MOVE( buffer, p, 10 );
|
||||
@ -125,8 +131,9 @@
|
||||
}
|
||||
|
||||
Found:
|
||||
/* We have found the start of the binary data. Now rewind and */
|
||||
/* extract the frame corresponding to the PostScript section. */
|
||||
/* We have found the start of the binary data or the `/sfnts' token. */
|
||||
/* Now rewind and extract the frame corresponding to this PostScript */
|
||||
/* section. */
|
||||
|
||||
ps_len = offset - base_offset;
|
||||
if ( FT_STREAM_SEEK( base_offset ) ||
|
||||
@ -140,9 +147,10 @@
|
||||
parser->root.limit = parser->root.cursor + ps_len;
|
||||
parser->num_dict = -1;
|
||||
|
||||
/* Finally, we check whether `StartData' was real -- it could be */
|
||||
/* in a comment or string. We also get its arguments to find out */
|
||||
/* whether the data is represented in binary or hex format. */
|
||||
/* Finally, we check whether `StartData' or `/sfnts' was real -- */
|
||||
/* it could be in a comment or string. We also get the arguments */
|
||||
/* of `StartData' to find out whether the data is represented in */
|
||||
/* binary or hex format. */
|
||||
|
||||
arg1 = parser->root.cursor;
|
||||
cid_parser_skip_PS_token( parser );
|
||||
@ -159,7 +167,7 @@
|
||||
if ( parser->root.error )
|
||||
break;
|
||||
|
||||
if ( *cur == 'S' && ft_strncmp( (char*)cur, "StartData", 9 ) == 0 )
|
||||
if ( cur[0] == 'S' && ft_strncmp( (char*)cur, "StartData", 9 ) == 0 )
|
||||
{
|
||||
if ( ft_strncmp( (char*)arg1, "(Hex)", 5 ) == 0 )
|
||||
parser->binary_length = ft_atol( (const char *)arg2 );
|
||||
@ -168,6 +176,12 @@
|
||||
cur = parser->root.cursor;
|
||||
goto Exit;
|
||||
}
|
||||
else if ( cur[1] == 's' && ft_strncmp( (char*)cur, "/sfnts", 6 ) == 0 )
|
||||
{
|
||||
FT_TRACE2(( "cid_parser_new: cannot handle Type 11 fonts\n" ));
|
||||
error = CID_Err_Unknown_File_Format;
|
||||
goto Exit;
|
||||
}
|
||||
|
||||
cid_parser_skip_PS_token( parser );
|
||||
cid_parser_skip_spaces ( parser );
|
||||
|
@ -4,7 +4,7 @@
|
||||
/* */
|
||||
/* CID token definitions (specification only). */
|
||||
/* */
|
||||
/* Copyright 1996-2001, 2002, 2003 by */
|
||||
/* Copyright 1996-2001, 2002, 2003, 2006 by */
|
||||
/* David Turner, Robert Wilhelm, and Werner Lemberg. */
|
||||
/* */
|
||||
/* This file is part of the FreeType project, and may only be used, */
|
||||
@ -21,17 +21,17 @@
|
||||
#undef T1CODE
|
||||
#define T1CODE T1_FIELD_LOCATION_CID_INFO
|
||||
|
||||
T1_FIELD_KEY ( "CIDFontName", cid_font_name )
|
||||
T1_FIELD_NUM ( "CIDFontVersion", cid_version )
|
||||
T1_FIELD_NUM ( "CIDFontType", cid_font_type )
|
||||
T1_FIELD_STRING( "Registry", registry )
|
||||
T1_FIELD_STRING( "Ordering", ordering )
|
||||
T1_FIELD_NUM ( "Supplement", supplement )
|
||||
T1_FIELD_NUM ( "UIDBase", uid_base )
|
||||
T1_FIELD_NUM ( "CIDMapOffset", cidmap_offset )
|
||||
T1_FIELD_NUM ( "FDBytes", fd_bytes )
|
||||
T1_FIELD_NUM ( "GDBytes", gd_bytes )
|
||||
T1_FIELD_NUM ( "CIDCount", cid_count )
|
||||
T1_FIELD_KEY ( "CIDFontName", cid_font_name, 0 )
|
||||
T1_FIELD_NUM ( "CIDFontVersion", cid_version, 0 )
|
||||
T1_FIELD_NUM ( "CIDFontType", cid_font_type, 0 )
|
||||
T1_FIELD_STRING( "Registry", registry, 0 )
|
||||
T1_FIELD_STRING( "Ordering", ordering, 0 )
|
||||
T1_FIELD_NUM ( "Supplement", supplement, 0 )
|
||||
T1_FIELD_NUM ( "UIDBase", uid_base, 0 )
|
||||
T1_FIELD_NUM ( "CIDMapOffset", cidmap_offset, 0 )
|
||||
T1_FIELD_NUM ( "FDBytes", fd_bytes, 0 )
|
||||
T1_FIELD_NUM ( "GDBytes", gd_bytes, 0 )
|
||||
T1_FIELD_NUM ( "CIDCount", cid_count, 0 )
|
||||
|
||||
|
||||
#undef FT_STRUCTURE
|
||||
@ -39,15 +39,15 @@
|
||||
#undef T1CODE
|
||||
#define T1CODE T1_FIELD_LOCATION_FONT_INFO
|
||||
|
||||
T1_FIELD_STRING( "version", version )
|
||||
T1_FIELD_STRING( "Notice", notice )
|
||||
T1_FIELD_STRING( "FullName", full_name )
|
||||
T1_FIELD_STRING( "FamilyName", family_name )
|
||||
T1_FIELD_STRING( "Weight", weight )
|
||||
T1_FIELD_NUM ( "ItalicAngle", italic_angle )
|
||||
T1_FIELD_BOOL ( "isFixedPitch", is_fixed_pitch )
|
||||
T1_FIELD_NUM ( "UnderlinePosition", underline_position )
|
||||
T1_FIELD_NUM ( "UnderlineThickness", underline_thickness )
|
||||
T1_FIELD_STRING( "version", version, 0 )
|
||||
T1_FIELD_STRING( "Notice", notice, 0 )
|
||||
T1_FIELD_STRING( "FullName", full_name, 0 )
|
||||
T1_FIELD_STRING( "FamilyName", family_name, 0 )
|
||||
T1_FIELD_STRING( "Weight", weight, 0 )
|
||||
T1_FIELD_NUM ( "ItalicAngle", italic_angle, 0 )
|
||||
T1_FIELD_BOOL ( "isFixedPitch", is_fixed_pitch, 0 )
|
||||
T1_FIELD_NUM ( "UnderlinePosition", underline_position, 0 )
|
||||
T1_FIELD_NUM ( "UnderlineThickness", underline_thickness, 0 )
|
||||
|
||||
|
||||
#undef FT_STRUCTURE
|
||||
@ -55,15 +55,15 @@
|
||||
#undef T1CODE
|
||||
#define T1CODE T1_FIELD_LOCATION_FONT_DICT
|
||||
|
||||
T1_FIELD_NUM ( "PaintType", paint_type )
|
||||
T1_FIELD_NUM ( "FontType", font_type )
|
||||
T1_FIELD_NUM ( "SubrMapOffset", subrmap_offset )
|
||||
T1_FIELD_NUM ( "SDBytes", sd_bytes )
|
||||
T1_FIELD_NUM ( "SubrCount", num_subrs )
|
||||
T1_FIELD_NUM ( "lenBuildCharArray", len_buildchar )
|
||||
T1_FIELD_FIXED( "ForceBoldThreshold", forcebold_threshold )
|
||||
T1_FIELD_FIXED( "ExpansionFactor", expansion_factor )
|
||||
T1_FIELD_FIXED( "StrokeWidth", stroke_width )
|
||||
T1_FIELD_NUM ( "PaintType", paint_type, 0 )
|
||||
T1_FIELD_NUM ( "FontType", font_type, 0 )
|
||||
T1_FIELD_NUM ( "SubrMapOffset", subrmap_offset, 0 )
|
||||
T1_FIELD_NUM ( "SDBytes", sd_bytes, 0 )
|
||||
T1_FIELD_NUM ( "SubrCount", num_subrs, 0 )
|
||||
T1_FIELD_NUM ( "lenBuildCharArray", len_buildchar, 0 )
|
||||
T1_FIELD_FIXED( "ForceBoldThreshold", forcebold_threshold, 0 )
|
||||
T1_FIELD_FIXED( "ExpansionFactor", expansion_factor, 0 )
|
||||
T1_FIELD_FIXED( "StrokeWidth", stroke_width, 0 )
|
||||
|
||||
|
||||
#undef FT_STRUCTURE
|
||||
@ -71,33 +71,33 @@
|
||||
#undef T1CODE
|
||||
#define T1CODE T1_FIELD_LOCATION_PRIVATE
|
||||
|
||||
T1_FIELD_NUM ( "UniqueID", unique_id )
|
||||
T1_FIELD_NUM ( "lenIV", lenIV )
|
||||
T1_FIELD_NUM ( "LanguageGroup", language_group )
|
||||
T1_FIELD_NUM ( "password", password )
|
||||
T1_FIELD_NUM ( "UniqueID", unique_id, 0 )
|
||||
T1_FIELD_NUM ( "lenIV", lenIV, 0 )
|
||||
T1_FIELD_NUM ( "LanguageGroup", language_group, 0 )
|
||||
T1_FIELD_NUM ( "password", password, 0 )
|
||||
|
||||
T1_FIELD_FIXED_1000( "BlueScale", blue_scale )
|
||||
T1_FIELD_NUM ( "BlueShift", blue_shift )
|
||||
T1_FIELD_NUM ( "BlueFuzz", blue_fuzz )
|
||||
T1_FIELD_FIXED_1000( "BlueScale", blue_scale, 0 )
|
||||
T1_FIELD_NUM ( "BlueShift", blue_shift, 0 )
|
||||
T1_FIELD_NUM ( "BlueFuzz", blue_fuzz, 0 )
|
||||
|
||||
T1_FIELD_NUM_TABLE ( "BlueValues", blue_values, 14 )
|
||||
T1_FIELD_NUM_TABLE ( "OtherBlues", other_blues, 10 )
|
||||
T1_FIELD_NUM_TABLE ( "FamilyBlues", family_blues, 14 )
|
||||
T1_FIELD_NUM_TABLE ( "FamilyOtherBlues", family_other_blues, 10 )
|
||||
T1_FIELD_NUM_TABLE ( "BlueValues", blue_values, 14, 0 )
|
||||
T1_FIELD_NUM_TABLE ( "OtherBlues", other_blues, 10, 0 )
|
||||
T1_FIELD_NUM_TABLE ( "FamilyBlues", family_blues, 14, 0 )
|
||||
T1_FIELD_NUM_TABLE ( "FamilyOtherBlues", family_other_blues, 10, 0 )
|
||||
|
||||
T1_FIELD_NUM_TABLE2( "StdHW", standard_width, 1 )
|
||||
T1_FIELD_NUM_TABLE2( "StdVW", standard_height, 1 )
|
||||
T1_FIELD_NUM_TABLE2( "MinFeature", min_feature, 2 )
|
||||
T1_FIELD_NUM_TABLE2( "StdHW", standard_width, 1, 0 )
|
||||
T1_FIELD_NUM_TABLE2( "StdVW", standard_height, 1, 0 )
|
||||
T1_FIELD_NUM_TABLE2( "MinFeature", min_feature, 2, 0 )
|
||||
|
||||
T1_FIELD_NUM_TABLE ( "StemSnapH", snap_widths, 12 )
|
||||
T1_FIELD_NUM_TABLE ( "StemSnapV", snap_heights, 12 )
|
||||
T1_FIELD_NUM_TABLE ( "StemSnapH", snap_widths, 12, 0 )
|
||||
T1_FIELD_NUM_TABLE ( "StemSnapV", snap_heights, 12, 0 )
|
||||
|
||||
#undef FT_STRUCTURE
|
||||
#define FT_STRUCTURE FT_BBox
|
||||
#undef T1CODE
|
||||
#define T1CODE T1_FIELD_LOCATION_BBOX
|
||||
|
||||
T1_FIELD_BBOX( "FontBBox", xMin )
|
||||
T1_FIELD_BBOX( "FontBBox", xMin, 0 )
|
||||
|
||||
|
||||
/* END */
|
||||
|
@ -554,6 +554,28 @@
|
||||
}
|
||||
|
||||
|
||||
static FT_ULong
|
||||
ft_gzip_get_uncompressed_size( FT_Stream stream )
|
||||
{
|
||||
FT_Error error;
|
||||
FT_ULong old_pos;
|
||||
FT_ULong result = 0;
|
||||
|
||||
|
||||
old_pos = stream->pos;
|
||||
if ( !FT_Stream_Seek( stream, stream->size - 4 ) )
|
||||
{
|
||||
result = (FT_ULong)FT_Stream_ReadLong( stream, &error );
|
||||
if ( error )
|
||||
result = 0;
|
||||
|
||||
FT_Stream_Seek( stream, old_pos );
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
FT_EXPORT_DEF( FT_Error )
|
||||
FT_Stream_OpenGzip( FT_Stream stream,
|
||||
FT_Stream source )
|
||||
@ -586,6 +608,52 @@
|
||||
stream->descriptor.pointer = zip;
|
||||
}
|
||||
|
||||
/*
|
||||
* We use the following trick to try to dramatically improve the
|
||||
* performance while dealing with small files. If the original stream
|
||||
* size is less than a certain threshold, we try to load the whole font
|
||||
* file into memory. This saves us from using the 32KB buffer needed
|
||||
* to inflate the file, plus the two 4KB intermediate input/output
|
||||
* buffers used in the `FT_GZipFile' structure.
|
||||
*/
|
||||
{
|
||||
FT_ULong zip_size = ft_gzip_get_uncompressed_size( source );
|
||||
|
||||
|
||||
if ( zip_size != 0 && zip_size < 40 * 1024 )
|
||||
{
|
||||
FT_Byte* zip_buff;
|
||||
|
||||
|
||||
if ( !FT_ALLOC( zip_buff, zip_size ) )
|
||||
{
|
||||
FT_ULong count;
|
||||
|
||||
|
||||
count = ft_gzip_file_io( zip, 0, zip_buff, zip_size );
|
||||
if ( count == zip_size )
|
||||
{
|
||||
ft_gzip_file_done( zip );
|
||||
FT_FREE( zip );
|
||||
|
||||
stream->descriptor.pointer = NULL;
|
||||
|
||||
stream->size = zip_size;
|
||||
stream->pos = 0;
|
||||
stream->base = zip_buff;
|
||||
stream->read = NULL;
|
||||
stream->close = ft_gzip_stream_close;
|
||||
|
||||
goto Exit;
|
||||
}
|
||||
|
||||
ft_gzip_file_io( zip, 0, NULL, 0 );
|
||||
FT_FREE( zip_buff );
|
||||
}
|
||||
error = 0;
|
||||
}
|
||||
}
|
||||
|
||||
stream->size = 0x7FFFFFFFL; /* don't know the real size! */
|
||||
stream->pos = 0;
|
||||
stream->base = 0;
|
||||
|
@ -131,6 +131,9 @@ uIntf *v /* working area: values in order of bit length */
|
||||
uInt z; /* number of entries in current table */
|
||||
|
||||
|
||||
/* Make comiler happy */
|
||||
r.base = 0;
|
||||
|
||||
/* Generate counts for each bit length */
|
||||
p = c;
|
||||
#define C0 *p++ = 0;
|
||||
|
@ -4,7 +4,7 @@
|
||||
/* */
|
||||
/* FreeType's OpenType validation module implementation (body). */
|
||||
/* */
|
||||
/* Copyright 2004, 2005 by */
|
||||
/* Copyright 2004, 2005, 2006 by */
|
||||
/* David Turner, Robert Wilhelm, and Werner Lemberg. */
|
||||
/* */
|
||||
/* This file is part of the FreeType project, and may only be used, */
|
||||
@ -39,10 +39,10 @@
|
||||
|
||||
|
||||
static FT_Error
|
||||
otv_load_table( FT_Face face,
|
||||
FT_Tag tag,
|
||||
FT_Byte* *table,
|
||||
FT_ULong *table_len )
|
||||
otv_load_table( FT_Face face,
|
||||
FT_Tag tag,
|
||||
FT_Byte* volatile* table,
|
||||
FT_ULong* table_len )
|
||||
{
|
||||
FT_Error error;
|
||||
FT_Memory memory = FT_FACE_MEMORY( face );
|
||||
@ -65,18 +65,22 @@
|
||||
|
||||
|
||||
static FT_Error
|
||||
otv_validate( FT_Face face,
|
||||
FT_UInt ot_flags,
|
||||
FT_Bytes *ot_base,
|
||||
FT_Bytes *ot_gdef,
|
||||
FT_Bytes *ot_gpos,
|
||||
FT_Bytes *ot_gsub,
|
||||
FT_Bytes *ot_jstf )
|
||||
otv_validate( FT_Face volatile face,
|
||||
FT_UInt ot_flags,
|
||||
FT_Bytes *ot_base,
|
||||
FT_Bytes *ot_gdef,
|
||||
FT_Bytes *ot_gpos,
|
||||
FT_Bytes *ot_gsub,
|
||||
FT_Bytes *ot_jstf )
|
||||
{
|
||||
FT_Error error = OTV_Err_Ok;
|
||||
FT_Byte *base, *gdef, *gpos, *gsub, *jstf;
|
||||
FT_ULong len_base, len_gdef, len_gpos, len_gsub, len_jstf;
|
||||
FT_ValidatorRec valid;
|
||||
FT_Error error = OTV_Err_Ok;
|
||||
FT_Byte* volatile base;
|
||||
FT_Byte* volatile gdef;
|
||||
FT_Byte* volatile gpos;
|
||||
FT_Byte* volatile gsub;
|
||||
FT_Byte* volatile jstf;
|
||||
FT_ULong len_base, len_gdef, len_gpos, len_gsub, len_jstf;
|
||||
FT_ValidatorRec volatile valid;
|
||||
|
||||
|
||||
base = gdef = gpos = gsub = jstf = NULL;
|
||||
@ -124,7 +128,7 @@
|
||||
if ( base )
|
||||
{
|
||||
ft_validator_init( &valid, base, base + len_base, FT_VALIDATE_DEFAULT );
|
||||
if ( ft_validator_run( &valid ) == 0 )
|
||||
if ( ft_setjmp( valid.jump_buffer ) == 0 )
|
||||
otv_BASE_validate( base, &valid );
|
||||
error = valid.error;
|
||||
if ( error )
|
||||
@ -134,7 +138,7 @@
|
||||
if ( gpos )
|
||||
{
|
||||
ft_validator_init( &valid, gpos, gpos + len_gpos, FT_VALIDATE_DEFAULT );
|
||||
if ( ft_validator_run( &valid ) == 0 )
|
||||
if ( ft_setjmp( valid.jump_buffer ) == 0 )
|
||||
otv_GPOS_validate( gpos, face->num_glyphs, &valid );
|
||||
error = valid.error;
|
||||
if ( error )
|
||||
@ -144,7 +148,7 @@
|
||||
if ( gsub )
|
||||
{
|
||||
ft_validator_init( &valid, gsub, gsub + len_gsub, FT_VALIDATE_DEFAULT );
|
||||
if ( ft_validator_run( &valid ) == 0 )
|
||||
if ( ft_setjmp( valid.jump_buffer ) == 0 )
|
||||
otv_GSUB_validate( gsub, face->num_glyphs, &valid );
|
||||
error = valid.error;
|
||||
if ( error )
|
||||
@ -154,7 +158,7 @@
|
||||
if ( gdef )
|
||||
{
|
||||
ft_validator_init( &valid, gdef, gdef + len_gdef, FT_VALIDATE_DEFAULT );
|
||||
if ( ft_validator_run( &valid ) == 0 )
|
||||
if ( ft_setjmp( valid.jump_buffer ) == 0 )
|
||||
otv_GDEF_validate( gdef, gsub, gpos, &valid );
|
||||
error = valid.error;
|
||||
if ( error )
|
||||
@ -164,7 +168,7 @@
|
||||
if ( jstf )
|
||||
{
|
||||
ft_validator_init( &valid, jstf, jstf + len_jstf, FT_VALIDATE_DEFAULT );
|
||||
if ( ft_validator_run( &valid ) == 0 )
|
||||
if ( ft_setjmp( valid.jump_buffer ) == 0 )
|
||||
otv_JSTF_validate( jstf, gsub, gpos, face->num_glyphs, &valid );
|
||||
error = valid.error;
|
||||
if ( error )
|
||||
@ -194,14 +198,14 @@
|
||||
|
||||
|
||||
static
|
||||
const FT_Service_OTvalidateRec otvalid_interface =
|
||||
const FT_Service_OTvalidateRec otvalid_interface =
|
||||
{
|
||||
otv_validate
|
||||
};
|
||||
|
||||
|
||||
static
|
||||
const FT_ServiceDescRec otvalid_services[] =
|
||||
const FT_ServiceDescRec otvalid_services[] =
|
||||
{
|
||||
{ FT_SERVICE_ID_OPENTYPE_VALIDATE, &otvalid_interface },
|
||||
{ NULL, NULL }
|
||||
|
@ -13,11 +13,11 @@ Glyph images are loaded into memory only on demand, thus leading to a small
|
||||
memory footprint.
|
||||
|
||||
Informations on the PCF font format can only be worked out from
|
||||
``pcfread.c'', and ``pcfwrite.c'', to be found, for instance, in the XFree86
|
||||
`pcfread.c', and `pcfwrite.c', to be found, for instance, in the XFree86
|
||||
(www.xfree86.org) source tree (xc/lib/font/bitmap/).
|
||||
|
||||
Many good bitmap fonts in bdf format come with XFree86: they can be
|
||||
compiled into the pcf format using the ``bdftopcf'' utility.
|
||||
compiled into the pcf format using the `bdftopcf' utility.
|
||||
|
||||
|
||||
Supported hardware
|
||||
@ -46,11 +46,11 @@ client application the work of interpreting them. For instance:
|
||||
FT_New_Face( library,..., &face );
|
||||
|
||||
pcfface = (PCF_Public_Face)face;
|
||||
|
||||
if ((pcfface->charset_registry == "ISO10646") &&
|
||||
|
||||
if ((pcfface->charset_registry == "ISO10646") &&
|
||||
(pcfface->charset_encoding) == "1")) [..]
|
||||
|
||||
Thus the driver always export ``ft_encoding_none'' as
|
||||
Thus the driver always export `ft_encoding_none' as
|
||||
face->charmap.encoding. FT_Get_Char_Index() behavior is unmodified, that
|
||||
is, it converts the ULong value given as argument into the corresponding
|
||||
glyph number.
|
||||
|
@ -4,7 +4,7 @@
|
||||
|
||||
# Copyright 2000, 2006 by
|
||||
# Francesco Zappa Nardelli
|
||||
#
|
||||
#
|
||||
# Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
# of this software and associated documentation files (the "Software"), to deal
|
||||
# in the Software without restriction, including without limitation the rights
|
||||
|
@ -203,19 +203,23 @@ THE SOFTWARE.
|
||||
|
||||
/* free properties */
|
||||
{
|
||||
PCF_Property prop = face->properties;
|
||||
PCF_Property prop;
|
||||
FT_Int i;
|
||||
|
||||
|
||||
for ( i = 0; i < face->nprops; i++ )
|
||||
if ( face->properties )
|
||||
{
|
||||
prop = &face->properties[i];
|
||||
for ( i = 0; i < face->nprops; i++ )
|
||||
{
|
||||
prop = &face->properties[i];
|
||||
|
||||
FT_FREE( prop->name );
|
||||
if ( prop->isString )
|
||||
FT_FREE( prop->value.atom );
|
||||
if ( prop ) {
|
||||
FT_FREE( prop->name );
|
||||
if ( prop->isString )
|
||||
FT_FREE( prop->value.atom );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
FT_FREE( face->properties );
|
||||
}
|
||||
|
||||
@ -258,6 +262,8 @@ THE SOFTWARE.
|
||||
FT_Error error2;
|
||||
|
||||
|
||||
PCF_Face_Done( pcfface );
|
||||
|
||||
/* this didn't work, try gzip support! */
|
||||
error2 = FT_Stream_OpenGzip( &face->gzip_stream, stream );
|
||||
if ( FT_ERROR_BASE( error2 ) == FT_Err_Unimplemented_Feature )
|
||||
@ -357,6 +363,7 @@ THE SOFTWARE.
|
||||
|
||||
Fail:
|
||||
FT_TRACE2(( "[not a valid PCF file]\n" ));
|
||||
PCF_Face_Done( pcfface );
|
||||
error = PCF_Err_Unknown_File_Format; /* error */
|
||||
goto Exit;
|
||||
}
|
||||
@ -435,7 +442,7 @@ THE SOFTWARE.
|
||||
|
||||
FT_TRACE4(( "load_glyph %d ---", glyph_index ));
|
||||
|
||||
if ( !face )
|
||||
if ( !face || glyph_index >= (FT_UInt)face->root.num_glyphs )
|
||||
{
|
||||
error = PCF_Err_Invalid_Argument;
|
||||
goto Exit;
|
||||
|
@ -2,7 +2,7 @@
|
||||
|
||||
FreeType font driver for pcf fonts
|
||||
|
||||
Copyright 2000, 2001, 2002, 2003, 2004, 2005, 2006 by
|
||||
Copyright 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007 by
|
||||
Francesco Zappa Nardelli
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
@ -102,7 +102,8 @@ THE SOFTWARE.
|
||||
return PCF_Err_Cannot_Open_Resource;
|
||||
|
||||
if ( toc->version != PCF_FILE_VERSION ||
|
||||
toc->count > FT_ARRAY_MAX( face->toc.tables ) )
|
||||
toc->count > FT_ARRAY_MAX( face->toc.tables ) ||
|
||||
toc->count == 0 )
|
||||
return PCF_Err_Invalid_File_Format;
|
||||
|
||||
if ( FT_NEW_ARRAY( face->toc.tables, toc->count ) )
|
||||
@ -116,6 +117,41 @@ THE SOFTWARE.
|
||||
tables++;
|
||||
}
|
||||
|
||||
/* Sort tables and check for overlaps. Because they are almost */
|
||||
/* always ordered already, an in-place bubble sort with simultaneous */
|
||||
/* boundary checking seems appropriate. */
|
||||
tables = face->toc.tables;
|
||||
|
||||
for ( n = 0; n < toc->count - 1; n++ )
|
||||
{
|
||||
FT_UInt i, have_change;
|
||||
|
||||
|
||||
have_change = 0;
|
||||
|
||||
for ( i = 0; i < toc->count - 1 - n; i++ )
|
||||
{
|
||||
PCF_TableRec tmp;
|
||||
|
||||
|
||||
if ( tables[i].offset > tables[i + 1].offset )
|
||||
{
|
||||
tmp = tables[i];
|
||||
tables[i] = tables[i + 1];
|
||||
tables[i + 1] = tmp;
|
||||
|
||||
have_change = 1;
|
||||
}
|
||||
|
||||
if ( ( tables[i].size > tables[i + 1].offset ) ||
|
||||
( tables[i].offset > tables[i + 1].offset - tables[i].size ) )
|
||||
return PCF_Err_Invalid_Offset;
|
||||
}
|
||||
|
||||
if ( !have_change )
|
||||
break;
|
||||
}
|
||||
|
||||
#if defined( FT_DEBUG_LEVEL_TRACE )
|
||||
|
||||
{
|
||||
@ -130,7 +166,8 @@ THE SOFTWARE.
|
||||
tables = face->toc.tables;
|
||||
for ( i = 0; i < toc->count; i++ )
|
||||
{
|
||||
for( j = 0; j < sizeof ( tableNames ) / sizeof ( tableNames[0] ); j++ )
|
||||
for ( j = 0; j < sizeof ( tableNames ) / sizeof ( tableNames[0] );
|
||||
j++ )
|
||||
if ( tables[i].type == (FT_UInt)( 1 << j ) )
|
||||
name = tableNames[j];
|
||||
|
||||
@ -153,13 +190,15 @@ THE SOFTWARE.
|
||||
}
|
||||
|
||||
|
||||
#define PCF_METRIC_SIZE 12
|
||||
|
||||
static
|
||||
const FT_Frame_Field pcf_metric_header[] =
|
||||
{
|
||||
#undef FT_STRUCTURE
|
||||
#define FT_STRUCTURE PCF_MetricRec
|
||||
|
||||
FT_FRAME_START( 12 ),
|
||||
FT_FRAME_START( PCF_METRIC_SIZE ),
|
||||
FT_FRAME_SHORT_LE( leftSideBearing ),
|
||||
FT_FRAME_SHORT_LE( rightSideBearing ),
|
||||
FT_FRAME_SHORT_LE( characterWidth ),
|
||||
@ -176,7 +215,7 @@ THE SOFTWARE.
|
||||
#undef FT_STRUCTURE
|
||||
#define FT_STRUCTURE PCF_MetricRec
|
||||
|
||||
FT_FRAME_START( 12 ),
|
||||
FT_FRAME_START( PCF_METRIC_SIZE ),
|
||||
FT_FRAME_SHORT( leftSideBearing ),
|
||||
FT_FRAME_SHORT( rightSideBearing ),
|
||||
FT_FRAME_SHORT( characterWidth ),
|
||||
@ -187,13 +226,15 @@ THE SOFTWARE.
|
||||
};
|
||||
|
||||
|
||||
#define PCF_COMPRESSED_METRIC_SIZE 5
|
||||
|
||||
static
|
||||
const FT_Frame_Field pcf_compressed_metric_header[] =
|
||||
{
|
||||
#undef FT_STRUCTURE
|
||||
#define FT_STRUCTURE PCF_Compressed_MetricRec
|
||||
|
||||
FT_FRAME_START( 5 ),
|
||||
FT_FRAME_START( PCF_COMPRESSED_METRIC_SIZE ),
|
||||
FT_FRAME_BYTE( leftSideBearing ),
|
||||
FT_FRAME_BYTE( rightSideBearing ),
|
||||
FT_FRAME_BYTE( characterWidth ),
|
||||
@ -221,7 +262,7 @@ THE SOFTWARE.
|
||||
? pcf_metric_msb_header
|
||||
: pcf_metric_header;
|
||||
|
||||
/* the following sets 'error' but doesn't return in case of failure */
|
||||
/* the following sets `error' but doesn't return in case of failure */
|
||||
(void)FT_STREAM_READ_FIELDS( fields, metric );
|
||||
}
|
||||
else
|
||||
@ -261,23 +302,26 @@ THE SOFTWARE.
|
||||
for ( i = 0; i < ntables; i++ )
|
||||
if ( tables[i].type == type )
|
||||
{
|
||||
if ( stream->pos > tables[i].offset ) {
|
||||
if ( stream->pos > tables[i].offset )
|
||||
{
|
||||
error = PCF_Err_Invalid_Stream_Skip;
|
||||
goto Fail;
|
||||
}
|
||||
|
||||
if ( FT_STREAM_SKIP( tables[i].offset - stream->pos ) ) {
|
||||
if ( FT_STREAM_SKIP( tables[i].offset - stream->pos ) )
|
||||
{
|
||||
error = PCF_Err_Invalid_Stream_Skip;
|
||||
goto Fail;
|
||||
}
|
||||
|
||||
*asize = tables[i].size; /* unused - to be removed */
|
||||
*asize = tables[i].size;
|
||||
*aformat = tables[i].format;
|
||||
|
||||
return PCF_Err_Ok;
|
||||
}
|
||||
|
||||
Fail:
|
||||
*asize = 0;
|
||||
return error;
|
||||
}
|
||||
|
||||
@ -298,13 +342,15 @@ THE SOFTWARE.
|
||||
}
|
||||
|
||||
|
||||
#define PCF_PROPERTY_SIZE 9
|
||||
|
||||
static
|
||||
const FT_Frame_Field pcf_property_header[] =
|
||||
{
|
||||
#undef FT_STRUCTURE
|
||||
#define FT_STRUCTURE PCF_ParsePropertyRec
|
||||
|
||||
FT_FRAME_START( 9 ),
|
||||
FT_FRAME_START( PCF_PROPERTY_SIZE ),
|
||||
FT_FRAME_LONG_LE( name ),
|
||||
FT_FRAME_BYTE ( isString ),
|
||||
FT_FRAME_LONG_LE( value ),
|
||||
@ -318,7 +364,7 @@ THE SOFTWARE.
|
||||
#undef FT_STRUCTURE
|
||||
#define FT_STRUCTURE PCF_ParsePropertyRec
|
||||
|
||||
FT_FRAME_START( 9 ),
|
||||
FT_FRAME_START( PCF_PROPERTY_SIZE ),
|
||||
FT_FRAME_LONG( name ),
|
||||
FT_FRAME_BYTE( isString ),
|
||||
FT_FRAME_LONG( value ),
|
||||
@ -353,8 +399,8 @@ THE SOFTWARE.
|
||||
PCF_Face face )
|
||||
{
|
||||
PCF_ParseProperty props = 0;
|
||||
PCF_Property properties = 0;
|
||||
FT_Int nprops, i;
|
||||
PCF_Property properties;
|
||||
FT_UInt nprops, i;
|
||||
FT_ULong format, size;
|
||||
FT_Error error;
|
||||
FT_Memory memory = FT_FACE(face)->memory;
|
||||
@ -390,6 +436,15 @@ THE SOFTWARE.
|
||||
|
||||
FT_TRACE4(( " nprop = %d\n", nprops ));
|
||||
|
||||
/* rough estimate */
|
||||
if ( nprops > size / PCF_PROPERTY_SIZE )
|
||||
{
|
||||
error = PCF_Err_Invalid_Table;
|
||||
goto Bail;
|
||||
}
|
||||
|
||||
face->nprops = nprops;
|
||||
|
||||
if ( FT_NEW_ARRAY( props, nprops ) )
|
||||
goto Bail;
|
||||
|
||||
@ -427,6 +482,13 @@ THE SOFTWARE.
|
||||
|
||||
FT_TRACE4(( " string_size = %ld\n", string_size ));
|
||||
|
||||
/* rough estimate */
|
||||
if ( string_size > size - nprops * PCF_PROPERTY_SIZE )
|
||||
{
|
||||
error = PCF_Err_Invalid_Table;
|
||||
goto Bail;
|
||||
}
|
||||
|
||||
if ( FT_NEW_ARRAY( strings, string_size ) )
|
||||
goto Bail;
|
||||
|
||||
@ -437,13 +499,24 @@ THE SOFTWARE.
|
||||
if ( FT_NEW_ARRAY( properties, nprops ) )
|
||||
goto Bail;
|
||||
|
||||
face->properties = properties;
|
||||
|
||||
for ( i = 0; i < nprops; i++ )
|
||||
{
|
||||
/* XXX: make atom */
|
||||
if ( FT_NEW_ARRAY( properties[i].name,
|
||||
ft_strlen( strings + props[i].name ) + 1 ) )
|
||||
FT_Long name_offset = props[i].name;
|
||||
|
||||
|
||||
if ( ( name_offset < 0 ) ||
|
||||
( (FT_ULong)name_offset > string_size ) )
|
||||
{
|
||||
error = PCF_Err_Invalid_Offset;
|
||||
goto Bail;
|
||||
ft_strcpy( properties[i].name, strings + props[i].name );
|
||||
}
|
||||
|
||||
if ( FT_NEW_ARRAY( properties[i].name,
|
||||
ft_strlen( strings + name_offset ) + 1 ) )
|
||||
goto Bail;
|
||||
ft_strcpy( properties[i].name, strings + name_offset );
|
||||
|
||||
FT_TRACE4(( " %s:", properties[i].name ));
|
||||
|
||||
@ -451,8 +524,18 @@ THE SOFTWARE.
|
||||
|
||||
if ( props[i].isString )
|
||||
{
|
||||
FT_Long value_offset = props[i].value;
|
||||
|
||||
|
||||
if ( ( value_offset < 0 ) ||
|
||||
( (FT_ULong)value_offset > string_size ) )
|
||||
{
|
||||
error = PCF_Err_Invalid_Offset;
|
||||
goto Bail;
|
||||
}
|
||||
|
||||
if ( FT_NEW_ARRAY( properties[i].value.atom,
|
||||
ft_strlen( strings + props[i].value ) + 1 ) )
|
||||
ft_strlen( strings + value_offset ) + 1 ) )
|
||||
goto Bail;
|
||||
ft_strcpy( properties[i].value.atom, strings + props[i].value );
|
||||
|
||||
@ -466,13 +549,7 @@ THE SOFTWARE.
|
||||
}
|
||||
}
|
||||
|
||||
face->properties = properties;
|
||||
face->nprops = nprops;
|
||||
|
||||
FT_FREE( props );
|
||||
FT_FREE( strings );
|
||||
|
||||
return PCF_Err_Ok;
|
||||
error = PCF_Err_Ok;
|
||||
|
||||
Bail:
|
||||
FT_FREE( props );
|
||||
@ -488,11 +565,9 @@ THE SOFTWARE.
|
||||
{
|
||||
FT_Error error = PCF_Err_Ok;
|
||||
FT_Memory memory = FT_FACE(face)->memory;
|
||||
FT_ULong format = 0;
|
||||
FT_ULong size = 0;
|
||||
FT_ULong format, size;
|
||||
PCF_Metric metrics = 0;
|
||||
int i;
|
||||
int nmetrics = -1;
|
||||
FT_ULong nmetrics, i;
|
||||
|
||||
|
||||
error = pcf_seek_to_table_type( stream,
|
||||
@ -504,7 +579,8 @@ THE SOFTWARE.
|
||||
if ( error )
|
||||
return error;
|
||||
|
||||
error = FT_READ_ULONG_LE( format );
|
||||
if ( FT_READ_ULONG_LE( format ) )
|
||||
goto Bail;
|
||||
|
||||
if ( !PCF_FORMAT_MATCH( format, PCF_DEFAULT_FORMAT ) &&
|
||||
!PCF_FORMAT_MATCH( format, PCF_COMPRESSED_METRICS ) )
|
||||
@ -524,16 +600,30 @@ THE SOFTWARE.
|
||||
else
|
||||
(void)FT_READ_USHORT_LE( nmetrics );
|
||||
}
|
||||
if ( error || nmetrics == -1 )
|
||||
if ( error )
|
||||
return PCF_Err_Invalid_File_Format;
|
||||
|
||||
face->nmetrics = nmetrics;
|
||||
|
||||
FT_TRACE4(( "pcf_get_metrics:\n" ));
|
||||
|
||||
FT_TRACE4(( " number of metrics: %d\n", nmetrics ));
|
||||
|
||||
/* rough estimate */
|
||||
if ( PCF_FORMAT_MATCH( format, PCF_DEFAULT_FORMAT ) )
|
||||
{
|
||||
if ( nmetrics > size / PCF_METRIC_SIZE )
|
||||
return PCF_Err_Invalid_Table;
|
||||
}
|
||||
else
|
||||
{
|
||||
if ( nmetrics > size / PCF_COMPRESSED_METRIC_SIZE )
|
||||
return PCF_Err_Invalid_Table;
|
||||
}
|
||||
|
||||
if ( FT_NEW_ARRAY( face->metrics, nmetrics ) )
|
||||
return PCF_Err_Out_Of_Memory;
|
||||
|
||||
FT_TRACE4(( "pcf_get_metrics:\n" ));
|
||||
|
||||
metrics = face->metrics;
|
||||
for ( i = 0; i < nmetrics; i++ )
|
||||
{
|
||||
@ -541,7 +631,7 @@ THE SOFTWARE.
|
||||
|
||||
metrics[i].bits = 0;
|
||||
|
||||
FT_TRACE4(( " idx %d: width=%d, "
|
||||
FT_TRACE5(( " idx %d: width=%d, "
|
||||
"lsb=%d, rsb=%d, ascent=%d, descent=%d, swidth=%d\n",
|
||||
i,
|
||||
( metrics + i )->characterWidth,
|
||||
@ -557,6 +647,8 @@ THE SOFTWARE.
|
||||
|
||||
if ( error )
|
||||
FT_FREE( face->metrics );
|
||||
|
||||
Bail:
|
||||
return error;
|
||||
}
|
||||
|
||||
@ -597,14 +689,16 @@ THE SOFTWARE.
|
||||
if ( !PCF_FORMAT_MATCH( format, PCF_DEFAULT_FORMAT ) )
|
||||
return PCF_Err_Invalid_File_Format;
|
||||
|
||||
FT_TRACE4(( "pcf_get_bitmaps:\n" ));
|
||||
|
||||
FT_TRACE4(( " number of bitmaps: %d\n", nbitmaps ));
|
||||
|
||||
if ( nbitmaps != face->nmetrics )
|
||||
return PCF_Err_Invalid_File_Format;
|
||||
|
||||
if ( FT_NEW_ARRAY( offsets, nbitmaps ) )
|
||||
return error;
|
||||
|
||||
FT_TRACE4(( "pcf_get_bitmaps:\n" ));
|
||||
|
||||
for ( i = 0; i < nbitmaps; i++ )
|
||||
{
|
||||
if ( PCF_BYTE_ORDER( format ) == MSBFirst )
|
||||
@ -612,7 +706,7 @@ THE SOFTWARE.
|
||||
else
|
||||
(void)FT_READ_LONG_LE( offsets[i] );
|
||||
|
||||
FT_TRACE4(( " bitmap %d: offset %ld (0x%lX)\n",
|
||||
FT_TRACE5(( " bitmap %d: offset %ld (0x%lX)\n",
|
||||
i, offsets[i], offsets[i] ));
|
||||
}
|
||||
if ( error )
|
||||
@ -640,15 +734,22 @@ THE SOFTWARE.
|
||||
FT_UNUSED( sizebitmaps ); /* only used for debugging */
|
||||
|
||||
for ( i = 0; i < nbitmaps; i++ )
|
||||
face->metrics[i].bits = stream->pos + offsets[i];
|
||||
{
|
||||
/* rough estimate */
|
||||
if ( ( offsets[i] < 0 ) ||
|
||||
( (FT_ULong)offsets[i] > size ) )
|
||||
{
|
||||
FT_ERROR(( "pcf_get_bitmaps:"));
|
||||
FT_ERROR(( " invalid offset to bitmap data of glyph %d\n", i ));
|
||||
}
|
||||
else
|
||||
face->metrics[i].bits = stream->pos + offsets[i];
|
||||
}
|
||||
|
||||
face->bitmapsFormat = format;
|
||||
|
||||
FT_FREE ( offsets );
|
||||
return error;
|
||||
|
||||
Bail:
|
||||
FT_FREE ( offsets );
|
||||
FT_FREE( offsets );
|
||||
return error;
|
||||
}
|
||||
|
||||
@ -734,7 +835,7 @@ THE SOFTWARE.
|
||||
|
||||
tmpEncoding[j].glyph = (FT_Short)encodingOffset;
|
||||
|
||||
FT_TRACE4(( " code %d (0x%04X): idx %d\n",
|
||||
FT_TRACE5(( " code %d (0x%04X): idx %d\n",
|
||||
tmpEncoding[j].enc, tmpEncoding[j].enc,
|
||||
tmpEncoding[j].glyph ));
|
||||
|
||||
@ -828,7 +929,8 @@ THE SOFTWARE.
|
||||
if ( error )
|
||||
goto Bail;
|
||||
|
||||
error = FT_READ_ULONG_LE( format );
|
||||
if ( FT_READ_ULONG_LE( format ) )
|
||||
goto Bail;
|
||||
|
||||
if ( !PCF_FORMAT_MATCH( format, PCF_DEFAULT_FORMAT ) &&
|
||||
!PCF_FORMAT_MATCH( format, PCF_ACCEL_W_INKBOUNDS ) )
|
||||
@ -876,7 +978,6 @@ THE SOFTWARE.
|
||||
accel->ink_minbounds = accel->minbounds; /* I'm not sure about this */
|
||||
accel->ink_maxbounds = accel->maxbounds;
|
||||
}
|
||||
return error;
|
||||
|
||||
Bail:
|
||||
return error;
|
||||
@ -1082,11 +1183,12 @@ THE SOFTWARE.
|
||||
else
|
||||
root->family_name = NULL;
|
||||
|
||||
/* Note: We shift all glyph indices by +1 since we must
|
||||
/*
|
||||
* Note: We shift all glyph indices by +1 since we must
|
||||
* respect the convention that glyph 0 always corresponds
|
||||
* to the "missing glyph".
|
||||
* to the `missing glyph'.
|
||||
*
|
||||
* This implies bumping the number of "available" glyphs by 1.
|
||||
* This implies bumping the number of `available' glyphs by 1.
|
||||
*/
|
||||
root->num_glyphs = face->nmetrics + 1;
|
||||
|
||||
@ -1171,7 +1273,7 @@ THE SOFTWARE.
|
||||
Exit:
|
||||
if ( error )
|
||||
{
|
||||
/* this is done to respect the behaviour of the original */
|
||||
/* This is done to respect the behaviour of the original */
|
||||
/* PCF font driver. */
|
||||
error = PCF_Err_Invalid_File_Format;
|
||||
}
|
||||
|
@ -2,7 +2,11 @@
|
||||
|
||||
Copyright 1990, 1994, 1998 The Open Group
|
||||
|
||||
All Rights Reserved.
|
||||
Permission to use, copy, modify, distribute, and sell this software and its
|
||||
documentation for any purpose is hereby granted without fee, provided that
|
||||
the above copyright notice appear in all copies and that both that
|
||||
copyright notice and this permission notice appear in supporting
|
||||
documentation.
|
||||
|
||||
The above copyright notice and this permission notice shall be included in
|
||||
all copies or substantial portions of the Software.
|
||||
@ -43,12 +47,12 @@ in this Software without prior written authorization from The Open Group.
|
||||
for ( ; --nbytes >= 0; buf++ )
|
||||
{
|
||||
unsigned int val = *buf;
|
||||
|
||||
|
||||
|
||||
val = ( ( val >> 1 ) & 0x55 ) | ( ( val << 1 ) & 0xAA );
|
||||
val = ( ( val >> 2 ) & 0x33 ) | ( ( val << 2 ) & 0xCC );
|
||||
val = ( ( val >> 4 ) & 0x0F ) | ( ( val << 4 ) & 0xF0 );
|
||||
|
||||
|
||||
*buf = (unsigned char)val;
|
||||
}
|
||||
}
|
||||
|
@ -13,7 +13,7 @@ UseFreeTypeHeaders ;
|
||||
|
||||
if $(FT2_MULTI)
|
||||
{
|
||||
_sources = pfrdrivr pfrgload pfrload pfrobjs pfrcmap pfrsbit ;
|
||||
_sources = pfrdrivr pfrgload pfrload pfrobjs pfrcmap pfrsbit ;
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -16,7 +16,7 @@
|
||||
/***************************************************************************/
|
||||
|
||||
|
||||
#include "pfrcmap.h"
|
||||
#include "pfrcmap.h"
|
||||
#include "pfrobjs.h"
|
||||
#include FT_INTERNAL_DEBUG_H
|
||||
|
||||
@ -29,12 +29,12 @@
|
||||
|
||||
cmap->num_chars = face->phy_font.num_chars;
|
||||
cmap->chars = face->phy_font.chars;
|
||||
|
||||
|
||||
/* just for safety, check that the character entries are correctly */
|
||||
/* sorted in increasing character code order */
|
||||
{
|
||||
FT_UInt n;
|
||||
|
||||
|
||||
|
||||
for ( n = 1; n < cmap->num_chars; n++ )
|
||||
{
|
||||
@ -42,7 +42,7 @@
|
||||
FT_ASSERT( 0 );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -31,7 +31,7 @@ FT_BEGIN_HEADER
|
||||
FT_CMapRec cmap;
|
||||
FT_UInt num_chars;
|
||||
PFR_Char chars;
|
||||
|
||||
|
||||
} PFR_CMapRec, *PFR_CMap;
|
||||
|
||||
|
||||
|
@ -54,11 +54,11 @@ FT_BEGIN_HEADER
|
||||
{
|
||||
FT_UInt type;
|
||||
PFR_ExtraItem_ParseFunc parser;
|
||||
|
||||
|
||||
} PFR_ExtraItemRec;
|
||||
|
||||
|
||||
typedef const struct PFR_ExtraItemRec_* PFR_ExtraItem;
|
||||
|
||||
|
||||
|
||||
FT_LOCAL( FT_Error )
|
||||
pfr_extra_items_skip( FT_Byte* *pp,
|
||||
@ -109,7 +109,7 @@ FT_BEGIN_HEADER
|
||||
FT_Memory memory );
|
||||
|
||||
/* */
|
||||
|
||||
|
||||
FT_END_HEADER
|
||||
|
||||
#endif /* __PFRLOAD_H__ */
|
||||
|
@ -4,7 +4,7 @@
|
||||
/* */
|
||||
/* FreeType PFR object methods (body). */
|
||||
/* */
|
||||
/* Copyright 2002, 2003, 2004, 2005, 2006 by */
|
||||
/* Copyright 2002, 2003, 2004, 2005, 2006, 2007 by */
|
||||
/* David Turner, Robert Wilhelm, and Werner Lemberg. */
|
||||
/* */
|
||||
/* This file is part of the FreeType project, and may only be used, */
|
||||
@ -122,15 +122,29 @@
|
||||
if ( error )
|
||||
goto Exit;
|
||||
|
||||
/* now, set-up all root face fields */
|
||||
/* now set up all root face fields */
|
||||
{
|
||||
PFR_PhyFont phy_font = &face->phy_font;
|
||||
|
||||
|
||||
pfrface->face_index = face_index;
|
||||
pfrface->num_glyphs = phy_font->num_chars;
|
||||
pfrface->num_glyphs = phy_font->num_chars + 1;
|
||||
pfrface->face_flags = FT_FACE_FLAG_SCALABLE;
|
||||
|
||||
/* if all characters point to the same gps_offset 0, we */
|
||||
/* assume that the font only contains bitmaps */
|
||||
{
|
||||
FT_UInt nn;
|
||||
|
||||
|
||||
for ( nn = 0; nn < phy_font->num_chars; nn++ )
|
||||
if ( phy_font->chars[nn].gps_offset != 0 )
|
||||
break;
|
||||
|
||||
if ( nn == phy_font->num_chars )
|
||||
pfrface->face_flags = 0; /* not scalable */
|
||||
}
|
||||
|
||||
if ( (phy_font->flags & PFR_PHY_PROPORTIONAL) == 0 )
|
||||
pfrface->face_flags |= FT_FACE_FLAG_FIXED_WIDTH;
|
||||
|
||||
@ -296,8 +310,11 @@
|
||||
if ( gindex > 0 )
|
||||
gindex--;
|
||||
|
||||
/* check that the glyph index is correct */
|
||||
FT_ASSERT( gindex < face->phy_font.num_chars );
|
||||
if ( !face || gindex >= face->phy_font.num_chars )
|
||||
{
|
||||
error = PFR_Err_Invalid_Argument;
|
||||
goto Exit;
|
||||
}
|
||||
|
||||
/* try to load an embedded bitmap */
|
||||
if ( ( load_flags & ( FT_LOAD_NO_SCALE | FT_LOAD_NO_BITMAP ) ) == 0 )
|
||||
@ -476,13 +493,14 @@
|
||||
goto Exit;
|
||||
|
||||
{
|
||||
FT_UInt count = item->pair_count;
|
||||
FT_UInt size = item->pair_size;
|
||||
FT_UInt power = (FT_UInt)ft_highpow2( (FT_UInt32)count );
|
||||
FT_UInt probe = power * size;
|
||||
FT_UInt extra = count - power;
|
||||
FT_Byte* base = stream->cursor;
|
||||
FT_Bool twobytes = FT_BOOL( item->flags & 1 );
|
||||
FT_UInt count = item->pair_count;
|
||||
FT_UInt size = item->pair_size;
|
||||
FT_UInt power = (FT_UInt)ft_highpow2( (FT_UInt32)count );
|
||||
FT_UInt probe = power * size;
|
||||
FT_UInt extra = count - power;
|
||||
FT_Byte* base = stream->cursor;
|
||||
FT_Bool twobytes = FT_BOOL( item->flags & 1 );
|
||||
FT_Bool twobyte_adj = FT_BOOL( item->flags & 2 );
|
||||
FT_Byte* p;
|
||||
FT_UInt32 cpair;
|
||||
|
||||
@ -500,7 +518,13 @@
|
||||
goto Found;
|
||||
|
||||
if ( cpair < pair )
|
||||
{
|
||||
if ( twobyte_adj )
|
||||
p += 2;
|
||||
else
|
||||
p++;
|
||||
base = p;
|
||||
}
|
||||
}
|
||||
|
||||
while ( probe > size )
|
||||
@ -533,7 +557,7 @@
|
||||
|
||||
|
||||
Found:
|
||||
if ( item->flags & 2 )
|
||||
if ( twobyte_adj )
|
||||
value = FT_PEEK_SHORT( p );
|
||||
else
|
||||
value = p[0];
|
||||
|
@ -331,11 +331,53 @@
|
||||
FT_UInt n )
|
||||
{
|
||||
FT_Byte* p;
|
||||
FT_UInt r = 0;
|
||||
FT_UInt r = 0;
|
||||
FT_UInt w = 0;
|
||||
FT_UInt pad = 0x01;
|
||||
|
||||
|
||||
n *= 2;
|
||||
for ( p = *cursor; r < n && p < limit; p++ )
|
||||
|
||||
#if 1
|
||||
|
||||
p = *cursor;
|
||||
if ( n > (FT_UInt)( limit - p ) )
|
||||
n = (FT_UInt)( limit - p );
|
||||
|
||||
/* we try to process two nibbles at a time to be as fast as possible */
|
||||
for ( ; r < n; r++ )
|
||||
{
|
||||
FT_UInt c = p[r];
|
||||
|
||||
|
||||
if ( IS_PS_SPACE( c ) )
|
||||
continue;
|
||||
|
||||
if ( c OP 0x80 )
|
||||
break;
|
||||
|
||||
c = ft_char_table[c & 0x7F];
|
||||
if ( (unsigned)c >= 16 )
|
||||
break;
|
||||
|
||||
pad = ( pad << 4 ) | c;
|
||||
if ( pad & 0x100 )
|
||||
{
|
||||
buffer[w++] = (FT_Byte)pad;
|
||||
pad = 0x01;
|
||||
}
|
||||
}
|
||||
|
||||
if ( pad != 0x01 )
|
||||
buffer[w++] = (FT_Byte)( pad << 4 );
|
||||
|
||||
*cursor = p + r;
|
||||
|
||||
return w;
|
||||
|
||||
#else /* 0 */
|
||||
|
||||
for ( r = 0; r < n; r++ )
|
||||
{
|
||||
FT_Char c;
|
||||
|
||||
@ -348,10 +390,10 @@
|
||||
|
||||
c = ft_char_table[*p & 0x7f];
|
||||
|
||||
if ( c < 0 || c >= 16 )
|
||||
if ( (unsigned)c >= 16 )
|
||||
break;
|
||||
|
||||
if ( r % 2 )
|
||||
if ( r & 1 )
|
||||
{
|
||||
*buffer = (FT_Byte)(*buffer + c);
|
||||
buffer++;
|
||||
@ -365,6 +407,9 @@
|
||||
*cursor = p;
|
||||
|
||||
return ( r + 1 ) / 2;
|
||||
|
||||
#endif /* 0 */
|
||||
|
||||
}
|
||||
|
||||
|
||||
@ -375,11 +420,32 @@
|
||||
FT_UInt n,
|
||||
FT_UShort* seed )
|
||||
{
|
||||
FT_Byte* p;
|
||||
FT_UInt r;
|
||||
FT_UShort s = *seed;
|
||||
FT_Byte* p;
|
||||
FT_UInt r;
|
||||
FT_UInt s = *seed;
|
||||
|
||||
|
||||
#if 1
|
||||
|
||||
p = *cursor;
|
||||
if ( n > (FT_UInt)(limit - p) )
|
||||
n = (FT_UInt)(limit - p);
|
||||
|
||||
for ( r = 0; r < n; r++ )
|
||||
{
|
||||
FT_UInt val = p[r];
|
||||
FT_UInt b = ( val ^ ( s >> 8 ) );
|
||||
|
||||
|
||||
s = ( (val + s)*52845U + 22719 ) & 0xFFFFU;
|
||||
buffer[r] = (FT_Byte) b;
|
||||
}
|
||||
|
||||
*cursor = p + n;
|
||||
*seed = (FT_UShort)s;
|
||||
|
||||
#else /* 0 */
|
||||
|
||||
for ( r = 0, p = *cursor; r < n && p < limit; r++, p++ )
|
||||
{
|
||||
FT_Byte b = (FT_Byte)( *p ^ ( s >> 8 ) );
|
||||
@ -388,10 +454,11 @@
|
||||
s = (FT_UShort)( ( *p + s ) * 52845U + 22719 );
|
||||
*buffer++ = b;
|
||||
}
|
||||
|
||||
*cursor = p;
|
||||
*seed = s;
|
||||
|
||||
#endif /* 0 */
|
||||
|
||||
return r;
|
||||
}
|
||||
|
||||
|
@ -63,42 +63,6 @@ FT_BEGIN_HEADER
|
||||
FT_UShort* seed );
|
||||
|
||||
|
||||
#define IS_PS_NEWLINE( ch ) \
|
||||
( ( ch ) == '\r' || \
|
||||
( ch ) == '\n' )
|
||||
|
||||
#define IS_PS_SPACE( ch ) \
|
||||
( ( ch ) == ' ' || \
|
||||
IS_PS_NEWLINE( ch ) || \
|
||||
( ch ) == '\t' || \
|
||||
( ch ) == '\f' || \
|
||||
( ch ) == '\0' )
|
||||
|
||||
#define IS_PS_SPECIAL( ch ) \
|
||||
( ( ch ) == '/' || \
|
||||
( ch ) == '(' || \
|
||||
( ch ) == ')' || \
|
||||
( ch ) == '<' || \
|
||||
( ch ) == '>' || \
|
||||
( ch ) == '[' || \
|
||||
( ch ) == ']' || \
|
||||
( ch ) == '{' || \
|
||||
( ch ) == '}' || \
|
||||
( ch ) == '%' )
|
||||
|
||||
#define IS_PS_DELIM( ch ) \
|
||||
( IS_PS_SPACE( ch ) || \
|
||||
IS_PS_SPECIAL( ch ) )
|
||||
|
||||
#define IS_PS_DIGIT( ch ) ( ( ch ) >= '0' && ( ch ) <= '9' )
|
||||
|
||||
#define IS_PS_XDIGIT( ch ) \
|
||||
( IS_PS_DIGIT( ( ch ) ) || \
|
||||
( ( ch ) >= 'A' && ( ch ) <= 'F' ) || \
|
||||
( ( ch ) >= 'a' && ( ch ) <= 'f' ) )
|
||||
|
||||
#define IS_PS_BASE85( ch ) ( ( ch ) >= '!' && ( ch ) <= 'u' )
|
||||
|
||||
FT_END_HEADER
|
||||
|
||||
#endif /* __PSCONV_H__ */
|
||||
|
@ -26,6 +26,16 @@
|
||||
#include "psauxerr.h"
|
||||
|
||||
|
||||
/*************************************************************************/
|
||||
/* */
|
||||
/* 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_psobjs
|
||||
|
||||
|
||||
/*************************************************************************/
|
||||
/*************************************************************************/
|
||||
/***** *****/
|
||||
@ -118,7 +128,7 @@
|
||||
}
|
||||
|
||||
/* copy elements and shift offsets */
|
||||
if (old_base )
|
||||
if ( old_base )
|
||||
{
|
||||
FT_MEM_COPY( table->block, old_base, table->capacity );
|
||||
shift_elements( table, old_base );
|
||||
@ -312,45 +322,94 @@
|
||||
}
|
||||
|
||||
|
||||
/* first character must be `(' */
|
||||
#define IS_OCTAL_DIGIT( c ) ( '0' <= (c) && (c) <= '7' )
|
||||
|
||||
static void
|
||||
|
||||
/* first character must be `('; */
|
||||
/* *acur is positioned at the character after the closing `)' */
|
||||
|
||||
static FT_Error
|
||||
skip_literal_string( FT_Byte* *acur,
|
||||
FT_Byte* limit )
|
||||
{
|
||||
FT_Byte* cur = *acur;
|
||||
FT_Int embed = 0;
|
||||
FT_Byte* cur = *acur;
|
||||
FT_Int embed = 0;
|
||||
FT_Error error = PSaux_Err_Invalid_File_Format;
|
||||
unsigned int i;
|
||||
|
||||
|
||||
while ( cur < limit )
|
||||
{
|
||||
if ( *cur == '\\' )
|
||||
cur++;
|
||||
else if ( *cur == '(' )
|
||||
FT_Byte c = *cur;
|
||||
|
||||
|
||||
++cur;
|
||||
|
||||
if ( c == '\\' )
|
||||
{
|
||||
/* Red Book 3rd ed., section `Literal Text Strings', p. 29: */
|
||||
/* A backslash can introduce three different types */
|
||||
/* of escape sequences: */
|
||||
/* - a special escaped char like \r, \n, etc. */
|
||||
/* - a one-, two-, or three-digit octal number */
|
||||
/* - none of the above in which case the backslash is ignored */
|
||||
|
||||
if ( cur == limit )
|
||||
/* error (or to be ignored?) */
|
||||
break;
|
||||
|
||||
switch ( *cur )
|
||||
{
|
||||
/* skip `special' escape */
|
||||
case 'n':
|
||||
case 'r':
|
||||
case 't':
|
||||
case 'b':
|
||||
case 'f':
|
||||
case '\\':
|
||||
case '(':
|
||||
case ')':
|
||||
++cur;
|
||||
break;
|
||||
|
||||
default:
|
||||
/* skip octal escape or ignore backslash */
|
||||
for ( i = 0; i < 3 && cur < limit; ++i )
|
||||
{
|
||||
if ( ! IS_OCTAL_DIGIT( *cur ) )
|
||||
break;
|
||||
|
||||
++cur;
|
||||
}
|
||||
}
|
||||
}
|
||||
else if ( c == '(' )
|
||||
embed++;
|
||||
else if ( *cur == ')' )
|
||||
else if ( c == ')' )
|
||||
{
|
||||
embed--;
|
||||
if ( embed == 0 )
|
||||
{
|
||||
cur++;
|
||||
error = PSaux_Err_Ok;
|
||||
break;
|
||||
}
|
||||
}
|
||||
cur++;
|
||||
}
|
||||
|
||||
*acur = cur;
|
||||
|
||||
return error;
|
||||
}
|
||||
|
||||
|
||||
/* first character must be `<' */
|
||||
|
||||
static void
|
||||
skip_string( PS_Parser parser )
|
||||
static FT_Error
|
||||
skip_string( FT_Byte* *acur,
|
||||
FT_Byte* limit )
|
||||
{
|
||||
FT_Byte* cur = parser->cursor;
|
||||
FT_Byte* limit = parser->limit;
|
||||
FT_Byte* cur = *acur;
|
||||
FT_Error err = PSaux_Err_Ok;
|
||||
|
||||
|
||||
while ( ++cur < limit )
|
||||
@ -367,12 +426,72 @@
|
||||
if ( cur < limit && *cur != '>' )
|
||||
{
|
||||
FT_ERROR(( "skip_string: missing closing delimiter `>'\n" ));
|
||||
parser->error = PSaux_Err_Invalid_File_Format;
|
||||
err = PSaux_Err_Invalid_File_Format;
|
||||
}
|
||||
else
|
||||
cur++;
|
||||
|
||||
parser->cursor = cur;
|
||||
*acur = cur;
|
||||
return err;
|
||||
}
|
||||
|
||||
|
||||
/* first character must be the opening brace that */
|
||||
/* starts the procedure */
|
||||
|
||||
/* NB: [ and ] need not match: */
|
||||
/* `/foo {[} def' is a valid PostScript fragment, */
|
||||
/* even within a Type1 font */
|
||||
|
||||
static FT_Error
|
||||
skip_procedure( FT_Byte* *acur,
|
||||
FT_Byte* limit )
|
||||
{
|
||||
FT_Byte* cur;
|
||||
FT_Int embed = 0;
|
||||
FT_Error error = PSaux_Err_Ok;
|
||||
|
||||
|
||||
FT_ASSERT( **acur == '{' );
|
||||
|
||||
for ( cur = *acur; cur < limit && error == PSaux_Err_Ok; ++cur )
|
||||
{
|
||||
switch ( *cur )
|
||||
{
|
||||
case '{':
|
||||
++embed;
|
||||
break;
|
||||
|
||||
case '}':
|
||||
--embed;
|
||||
if ( embed == 0 )
|
||||
{
|
||||
++cur;
|
||||
goto end;
|
||||
}
|
||||
break;
|
||||
|
||||
case '(':
|
||||
error = skip_literal_string( &cur, limit );
|
||||
break;
|
||||
|
||||
case '<':
|
||||
error = skip_string( &cur, limit );
|
||||
break;
|
||||
|
||||
case '%':
|
||||
skip_comment( &cur, limit );
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
end:
|
||||
if ( embed != 0 )
|
||||
error = PSaux_Err_Invalid_File_Format;
|
||||
|
||||
*acur = cur;
|
||||
|
||||
return error;
|
||||
}
|
||||
|
||||
|
||||
@ -393,6 +512,7 @@
|
||||
|
||||
FT_Byte* cur = parser->cursor;
|
||||
FT_Byte* limit = parser->limit;
|
||||
FT_Error error = PSaux_Err_Ok;
|
||||
|
||||
|
||||
skip_spaces( &cur, limit ); /* this also skips comments */
|
||||
@ -400,16 +520,23 @@
|
||||
goto Exit;
|
||||
|
||||
/* self-delimiting, single-character tokens */
|
||||
if ( *cur == '[' || *cur == ']' ||
|
||||
*cur == '{' || *cur == '}' )
|
||||
if ( *cur == '[' || *cur == ']' )
|
||||
{
|
||||
cur++;
|
||||
goto Exit;
|
||||
}
|
||||
|
||||
/* skip balanced expressions (procedures and strings) */
|
||||
|
||||
if ( *cur == '{' ) /* {...} */
|
||||
{
|
||||
error = skip_procedure( &cur, limit );
|
||||
goto Exit;
|
||||
}
|
||||
|
||||
if ( *cur == '(' ) /* (...) */
|
||||
{
|
||||
skip_literal_string( &cur, limit );
|
||||
error = skip_literal_string( &cur, limit );
|
||||
goto Exit;
|
||||
}
|
||||
|
||||
@ -419,11 +546,11 @@
|
||||
{
|
||||
cur++;
|
||||
cur++;
|
||||
goto Exit;
|
||||
}
|
||||
parser->cursor = cur;
|
||||
skip_string( parser );
|
||||
return;
|
||||
else
|
||||
error = skip_string( &cur, limit );
|
||||
|
||||
goto Exit;
|
||||
}
|
||||
|
||||
if ( *cur == '>' )
|
||||
@ -433,7 +560,7 @@
|
||||
{
|
||||
FT_ERROR(( "ps_parser_skip_PS_token: "
|
||||
"unexpected closing delimiter `>'\n" ));
|
||||
parser->error = PSaux_Err_Invalid_File_Format;
|
||||
error = PSaux_Err_Invalid_File_Format;
|
||||
goto Exit;
|
||||
}
|
||||
cur++;
|
||||
@ -446,20 +573,27 @@
|
||||
/* anything else */
|
||||
while ( cur < limit )
|
||||
{
|
||||
if ( *cur == ')' )
|
||||
{
|
||||
FT_ERROR(( "ps_parser_skip_PS_token: "
|
||||
"unexpected closing delimiter `)'\n" ));
|
||||
parser->error = PSaux_Err_Invalid_File_Format;
|
||||
goto Exit;
|
||||
}
|
||||
else if ( IS_PS_DELIM( *cur ) )
|
||||
/* *cur might be invalid (e.g., ')' or '}'), but this */
|
||||
/* is handled by the test `cur == parser->cursor' below */
|
||||
if ( IS_PS_DELIM( *cur ) )
|
||||
break;
|
||||
|
||||
cur++;
|
||||
}
|
||||
|
||||
Exit:
|
||||
if ( cur == parser->cursor )
|
||||
{
|
||||
FT_ERROR(( "ps_parser_skip_PS_token: "
|
||||
"current token is `%c', which is self-delimiting "
|
||||
"but invalid at this point\n",
|
||||
*cur ));
|
||||
|
||||
error = PSaux_Err_Invalid_File_Format;
|
||||
}
|
||||
|
||||
FT_ASSERT( parser->error == PSaux_Err_Ok );
|
||||
parser->error = error;
|
||||
parser->cursor = cur;
|
||||
}
|
||||
|
||||
@ -480,7 +614,6 @@
|
||||
{
|
||||
FT_Byte* cur;
|
||||
FT_Byte* limit;
|
||||
FT_Byte starter, ender;
|
||||
FT_Int embed;
|
||||
|
||||
|
||||
@ -503,26 +636,27 @@
|
||||
case '(':
|
||||
token->type = T1_TOKEN_TYPE_STRING;
|
||||
token->start = cur;
|
||||
skip_literal_string( &cur, limit );
|
||||
if ( cur < limit )
|
||||
|
||||
if ( skip_literal_string( &cur, limit ) == PSaux_Err_Ok )
|
||||
token->limit = cur;
|
||||
break;
|
||||
|
||||
/************* check for programs/array *****************/
|
||||
case '{':
|
||||
token->type = T1_TOKEN_TYPE_ARRAY;
|
||||
ender = '}';
|
||||
goto Lookup_Ender;
|
||||
token->type = T1_TOKEN_TYPE_ARRAY;
|
||||
token->start = cur;
|
||||
|
||||
if ( skip_procedure( &cur, limit ) == PSaux_Err_Ok )
|
||||
token->limit = cur;
|
||||
break;
|
||||
|
||||
/************* check for table/array ********************/
|
||||
/* XXX: in theory we should also look for "<<" */
|
||||
/* since this is semantically equivalent to "["; */
|
||||
/* in practice it doesn't matter (?) */
|
||||
case '[':
|
||||
token->type = T1_TOKEN_TYPE_ARRAY;
|
||||
ender = ']';
|
||||
/* fall through */
|
||||
|
||||
Lookup_Ender:
|
||||
token->type = T1_TOKEN_TYPE_ARRAY;
|
||||
embed = 1;
|
||||
starter = *cur;
|
||||
token->start = cur++;
|
||||
|
||||
/* we need this to catch `[ ]' */
|
||||
@ -532,9 +666,11 @@
|
||||
|
||||
while ( cur < limit && !parser->error )
|
||||
{
|
||||
if ( *cur == starter )
|
||||
/* XXX: this is wrong because it does not */
|
||||
/* skip comments, procedures, and strings */
|
||||
if ( *cur == '[' )
|
||||
embed++;
|
||||
else if ( *cur == ender )
|
||||
else if ( *cur == ']' )
|
||||
{
|
||||
embed--;
|
||||
if ( embed <= 0 )
|
||||
@ -555,7 +691,7 @@
|
||||
/* ************ otherwise, it is any token **************/
|
||||
default:
|
||||
token->start = cur;
|
||||
token->type = T1_TOKEN_TYPE_ANY;
|
||||
token->type = ( *cur == '/' ? T1_TOKEN_TYPE_KEY : T1_TOKEN_TYPE_ANY );
|
||||
ps_parser_skip_PS_token( parser );
|
||||
cur = parser->cursor;
|
||||
if ( !parser->error )
|
||||
@ -572,6 +708,9 @@
|
||||
}
|
||||
|
||||
|
||||
/* NB: `tokens' can be NULL if we only want to count */
|
||||
/* the number of array elements */
|
||||
|
||||
FT_LOCAL_DEF( void )
|
||||
ps_parser_to_token_array( PS_Parser parser,
|
||||
T1_Token tokens,
|
||||
@ -607,7 +746,7 @@
|
||||
if ( !token.type )
|
||||
break;
|
||||
|
||||
if ( cur < limit )
|
||||
if ( tokens != NULL && cur < limit )
|
||||
*cur = token;
|
||||
|
||||
cur++;
|
||||
@ -622,6 +761,8 @@
|
||||
|
||||
|
||||
/* first character must be a delimiter or a part of a number */
|
||||
/* NB: `coords' can be NULL if we just want to skip the */
|
||||
/* array; in this case we ignore `max_coords' */
|
||||
|
||||
static FT_Int
|
||||
ps_tocoordarray( FT_Byte* *acur,
|
||||
@ -654,21 +795,26 @@
|
||||
/* now, read the coordinates */
|
||||
while ( cur < limit )
|
||||
{
|
||||
FT_Short dummy;
|
||||
|
||||
|
||||
/* skip whitespace in front of data */
|
||||
skip_spaces( &cur, limit );
|
||||
if ( cur >= limit )
|
||||
goto Exit;
|
||||
|
||||
if ( count >= max_coords )
|
||||
if ( coords != NULL && count >= max_coords )
|
||||
break;
|
||||
|
||||
if ( c == ender )
|
||||
if ( *cur == ender )
|
||||
{
|
||||
cur++;
|
||||
break;
|
||||
}
|
||||
|
||||
coords[count] =
|
||||
/* call PS_Conv_ToFixed() even if coords == NULL */
|
||||
/* to properly parse number at `cur' */
|
||||
*( coords != NULL ? &coords[count] : &dummy ) =
|
||||
(FT_Short)( PS_Conv_ToFixed( &cur, limit, 0 ) >> 16 );
|
||||
count++;
|
||||
|
||||
@ -683,6 +829,8 @@
|
||||
|
||||
|
||||
/* first character must be a delimiter or a part of a number */
|
||||
/* NB: `values' can be NULL if we just want to skip the */
|
||||
/* array in this case we ignore `max_values' */
|
||||
|
||||
static FT_Int
|
||||
ps_tofixedarray( FT_Byte* *acur,
|
||||
@ -716,21 +864,27 @@
|
||||
/* now, read the values */
|
||||
while ( cur < limit )
|
||||
{
|
||||
FT_Fixed dummy;
|
||||
|
||||
|
||||
/* skip whitespace in front of data */
|
||||
skip_spaces( &cur, limit );
|
||||
if ( cur >= limit )
|
||||
goto Exit;
|
||||
|
||||
if ( count >= max_values )
|
||||
if ( values != NULL && count >= max_values )
|
||||
break;
|
||||
|
||||
if ( c == ender )
|
||||
if ( *cur == ender )
|
||||
{
|
||||
cur++;
|
||||
break;
|
||||
}
|
||||
|
||||
values[count] = PS_Conv_ToFixed( &cur, limit, power_ten );
|
||||
/* call PS_Conv_ToFixed() even if coords == NULL */
|
||||
/* to properly parse number at `cur' */
|
||||
*( values != NULL ? &values[count] : &dummy ) =
|
||||
PS_Conv_ToFixed( &cur, limit, power_ten );
|
||||
count++;
|
||||
|
||||
if ( !ender )
|
||||
@ -957,18 +1111,41 @@
|
||||
if ( cur >= limit )
|
||||
break;
|
||||
|
||||
if ( field->type == T1_FIELD_TYPE_KEY )
|
||||
/* we allow both a string or a name */
|
||||
/* for cases like /FontName (foo) def */
|
||||
if ( token.type == T1_TOKEN_TYPE_KEY )
|
||||
{
|
||||
/* don't include leading `/' */
|
||||
len--;
|
||||
cur++;
|
||||
}
|
||||
else
|
||||
else if ( token.type == T1_TOKEN_TYPE_STRING )
|
||||
{
|
||||
/* don't include delimiting parentheses */
|
||||
/* don't include delimiting parentheses */
|
||||
/* XXX we don't handle <<...>> here */
|
||||
/* XXX should we convert octal escapes? */
|
||||
/* if so, what encoding should we use? */
|
||||
cur++;
|
||||
len -= 2;
|
||||
}
|
||||
else
|
||||
{
|
||||
FT_ERROR(( "ps_parser_load_field: expected a name or string "
|
||||
"but found token of type %d instead\n",
|
||||
token.type ));
|
||||
error = PSaux_Err_Invalid_File_Format;
|
||||
goto Exit;
|
||||
}
|
||||
|
||||
/* for this to work (FT_String**)q must have been */
|
||||
/* initialized to NULL */
|
||||
if ( *(FT_String**)q != NULL )
|
||||
{
|
||||
FT_TRACE0(( "ps_parser_load_field: overwriting field %s\n",
|
||||
field->ident ));
|
||||
FT_FREE( *(FT_String**)q );
|
||||
*(FT_String**)q = NULL;
|
||||
}
|
||||
|
||||
if ( FT_ALLOC( string, len + 1 ) )
|
||||
goto Exit;
|
||||
@ -1038,11 +1215,10 @@
|
||||
T1_FieldRec fieldrec = *(T1_Field)field;
|
||||
|
||||
|
||||
#if 1
|
||||
fieldrec.type = T1_FIELD_TYPE_INTEGER;
|
||||
if ( field->type == T1_FIELD_TYPE_FIXED_ARRAY )
|
||||
if ( field->type == T1_FIELD_TYPE_FIXED_ARRAY ||
|
||||
field->type == T1_FIELD_TYPE_BBOX )
|
||||
fieldrec.type = T1_FIELD_TYPE_FIXED;
|
||||
#endif
|
||||
|
||||
ps_parser_to_token_array( parser, elements,
|
||||
T1_MAX_TABLE_ELEMENTS, &num_elements );
|
||||
@ -1057,9 +1233,10 @@
|
||||
old_cursor = parser->cursor;
|
||||
old_limit = parser->limit;
|
||||
|
||||
/* we store the elements count */
|
||||
*(FT_Byte*)( (FT_Byte*)objects[0] + field->count_offset ) =
|
||||
(FT_Byte)num_elements;
|
||||
/* we store the elements count if necessary */
|
||||
if ( field->type != T1_FIELD_TYPE_BBOX )
|
||||
*(FT_Byte*)( (FT_Byte*)objects[0] + field->count_offset ) =
|
||||
(FT_Byte)num_elements;
|
||||
|
||||
/* we now load each element, adjusting the field.offset on each one */
|
||||
token = elements;
|
||||
@ -1105,8 +1282,8 @@
|
||||
{
|
||||
FT_Error error = PSaux_Err_Ok;
|
||||
FT_Byte* cur;
|
||||
|
||||
|
||||
|
||||
|
||||
ps_parser_skip_spaces( parser );
|
||||
cur = parser->cursor;
|
||||
|
||||
|
@ -276,7 +276,8 @@
|
||||
return psnames->unicodes_init( memory,
|
||||
unicodes,
|
||||
face->type1.num_glyphs,
|
||||
(PS_Glyph_NameFunc)&t1_get_glyph_name,
|
||||
(PS_GetGlyphNameFunc)&t1_get_glyph_name,
|
||||
(PS_FreeGlyphNameFunc)NULL,
|
||||
(FT_Pointer)face );
|
||||
}
|
||||
|
||||
|
@ -4,7 +4,7 @@
|
||||
/* */
|
||||
/* PostScript Type 1 decoding routines (body). */
|
||||
/* */
|
||||
/* Copyright 2000-2001, 2002, 2003, 2004, 2005 by */
|
||||
/* Copyright 2000-2001, 2002, 2003, 2004, 2005, 2006 by */
|
||||
/* David Turner, Robert Wilhelm, and Werner Lemberg. */
|
||||
/* */
|
||||
/* This file is part of the FreeType project, and may only be used, */
|
||||
@ -65,6 +65,7 @@
|
||||
op_pop,
|
||||
op_return,
|
||||
op_setcurrentpoint,
|
||||
op_unknown15,
|
||||
|
||||
op_max /* never remove this one */
|
||||
|
||||
@ -99,7 +100,8 @@
|
||||
1, /* callsubr */
|
||||
0, /* pop */
|
||||
0, /* return */
|
||||
2 /* setcurrentpoint */
|
||||
2, /* setcurrentpoint */
|
||||
2 /* opcode 15 (undocumented and obsolete) */
|
||||
};
|
||||
|
||||
|
||||
@ -323,6 +325,8 @@
|
||||
FT_Byte* limit;
|
||||
T1_Builder builder = &decoder->builder;
|
||||
FT_Pos x, y, orig_x, orig_y;
|
||||
FT_Int known_othersubr_result_cnt = 0;
|
||||
FT_Int unknown_othersubr_result_cnt = 0;
|
||||
|
||||
T1_Hints_Funcs hinter;
|
||||
|
||||
@ -344,6 +348,19 @@
|
||||
|
||||
hinter = (T1_Hints_Funcs)builder->hints_funcs;
|
||||
|
||||
/* a font that reads BuildCharArray without setting */
|
||||
/* its values first is buggy, but ... */
|
||||
FT_ASSERT( ( decoder->len_buildchar == 0 ) ==
|
||||
( decoder->buildchar == NULL ) );
|
||||
|
||||
if ( decoder->len_buildchar > 0 )
|
||||
memset( &decoder->buildchar[0],
|
||||
0,
|
||||
sizeof( decoder->buildchar[0] ) *
|
||||
decoder->len_buildchar );
|
||||
|
||||
FT_TRACE4(( "\nStart charstring\n" ));
|
||||
|
||||
zone->base = charstring_base;
|
||||
limit = zone->limit = charstring_base + charstring_len;
|
||||
ip = zone->cursor = zone->base;
|
||||
@ -365,6 +382,11 @@
|
||||
FT_Long value = 0;
|
||||
|
||||
|
||||
FT_ASSERT( known_othersubr_result_cnt == 0 ||
|
||||
unknown_othersubr_result_cnt == 0 );
|
||||
|
||||
FT_TRACE5(( " (%d)", decoder->top - decoder->stack ));
|
||||
|
||||
/*********************************************************************/
|
||||
/* */
|
||||
/* Decode operator or operand */
|
||||
@ -414,7 +436,7 @@
|
||||
break;
|
||||
|
||||
case 15: /* undocumented, obsolete operator */
|
||||
op = op_none;
|
||||
op = op_unknown15;
|
||||
break;
|
||||
|
||||
case 21:
|
||||
@ -520,6 +542,23 @@
|
||||
}
|
||||
}
|
||||
|
||||
if ( unknown_othersubr_result_cnt > 0 )
|
||||
{
|
||||
switch ( op )
|
||||
{
|
||||
case op_callsubr:
|
||||
case op_return:
|
||||
case op_none:
|
||||
case op_pop:
|
||||
break;
|
||||
|
||||
default:
|
||||
/* all operands have been transferred by previous pops */
|
||||
unknown_othersubr_result_cnt = 0;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/*********************************************************************/
|
||||
/* */
|
||||
/* Push value on stack, or process operator */
|
||||
@ -540,16 +579,59 @@
|
||||
}
|
||||
else if ( op == op_callothersubr ) /* callothersubr */
|
||||
{
|
||||
FT_Int subr_no;
|
||||
FT_Int arg_cnt;
|
||||
|
||||
|
||||
FT_TRACE4(( " callothersubr" ));
|
||||
|
||||
if ( top - decoder->stack < 2 )
|
||||
goto Stack_Underflow;
|
||||
|
||||
top -= 2;
|
||||
switch ( (FT_Int)top[1] )
|
||||
|
||||
subr_no = (FT_Int)top[1];
|
||||
arg_cnt = (FT_Int)top[0];
|
||||
|
||||
/***********************************************************/
|
||||
/* */
|
||||
/* remove all operands to callothersubr from the stack */
|
||||
/* */
|
||||
/* for handled othersubrs, where we know the number of */
|
||||
/* arguments, we increase the stack by the value of */
|
||||
/* known_othersubr_result_cnt */
|
||||
/* */
|
||||
/* for unhandled othersubrs the following pops adjust the */
|
||||
/* stack pointer as necessary */
|
||||
|
||||
if ( arg_cnt > top - decoder->stack )
|
||||
goto Stack_Underflow;
|
||||
|
||||
top -= arg_cnt;
|
||||
|
||||
known_othersubr_result_cnt = 0;
|
||||
unknown_othersubr_result_cnt = 0;
|
||||
|
||||
/* XXX TODO: The checks to `arg_count == <whatever>' */
|
||||
/* might not be correct; an othersubr expects a certain */
|
||||
/* number of operands on the PostScript stack (as opposed */
|
||||
/* to the T1 stack) but it doesn't have to put them there */
|
||||
/* by itself; previous othersubrs might have left the */
|
||||
/* operands there if they were not followed by an */
|
||||
/* appropriate number of pops */
|
||||
/* */
|
||||
/* On the other hand, Adobe Reader 7.0.8 for Linux doesn't */
|
||||
/* accept a font that contains charstrings like */
|
||||
/* */
|
||||
/* 100 200 2 20 callothersubr */
|
||||
/* 300 1 20 callothersubr pop */
|
||||
/* */
|
||||
/* Perhaps this is the reason why BuildCharArray exists. */
|
||||
|
||||
switch ( subr_no )
|
||||
{
|
||||
case 1: /* start flex feature */
|
||||
if ( top[0] != 0 )
|
||||
if ( arg_cnt != 0 )
|
||||
goto Unexpected_OtherSubr;
|
||||
|
||||
decoder->flex_state = 1;
|
||||
@ -564,7 +646,7 @@
|
||||
FT_Int idx;
|
||||
|
||||
|
||||
if ( top[0] != 0 )
|
||||
if ( arg_cnt != 0 )
|
||||
goto Unexpected_OtherSubr;
|
||||
|
||||
/* note that we should not add a point for index 0; */
|
||||
@ -580,7 +662,7 @@
|
||||
break;
|
||||
|
||||
case 0: /* end flex feature */
|
||||
if ( top[0] != 3 )
|
||||
if ( arg_cnt != 3 )
|
||||
goto Unexpected_OtherSubr;
|
||||
|
||||
if ( decoder->flex_state == 0 ||
|
||||
@ -591,40 +673,15 @@
|
||||
goto Syntax_Error;
|
||||
}
|
||||
|
||||
/* now consume the remaining `pop pop setcurpoint' */
|
||||
if ( ip + 6 > limit ||
|
||||
ip[0] != 12 || ip[1] != 17 || /* pop */
|
||||
ip[2] != 12 || ip[3] != 17 || /* pop */
|
||||
ip[4] != 12 || ip[5] != 33 ) /* setcurpoint */
|
||||
{
|
||||
FT_ERROR(( "t1_decoder_parse_charstrings: "
|
||||
"invalid flex charstring\n" ));
|
||||
goto Syntax_Error;
|
||||
}
|
||||
|
||||
ip += 6;
|
||||
decoder->flex_state = 0;
|
||||
/* the two `results' are popped by the following setcurrentpoint */
|
||||
known_othersubr_result_cnt = 2;
|
||||
break;
|
||||
|
||||
case 3: /* change hints */
|
||||
if ( top[0] != 1 )
|
||||
if ( arg_cnt != 1 )
|
||||
goto Unexpected_OtherSubr;
|
||||
|
||||
/* eat the following `pop' */
|
||||
if ( ip + 2 > limit )
|
||||
{
|
||||
FT_ERROR(( "t1_decoder_parse_charstrings: "
|
||||
"invalid escape (12+%d)\n", ip[-1] ));
|
||||
goto Syntax_Error;
|
||||
}
|
||||
|
||||
if ( ip[0] != 12 || ip[1] != 17 )
|
||||
{
|
||||
FT_ERROR(( "t1_decoder_parse_charstrings: " ));
|
||||
FT_ERROR(( "`pop' expected, found (%d %d)\n", ip[0], ip[1] ));
|
||||
goto Syntax_Error;
|
||||
}
|
||||
ip += 2;
|
||||
known_othersubr_result_cnt = 1;
|
||||
|
||||
if ( hinter )
|
||||
hinter->reset( hinter->hints, builder->current->n_points );
|
||||
@ -656,18 +713,14 @@
|
||||
goto Syntax_Error;
|
||||
}
|
||||
|
||||
num_points = (FT_UInt)top[1] - 13 + ( top[1] == 18 );
|
||||
if ( top[0] != (FT_Int)( num_points * blend->num_designs ) )
|
||||
num_points = (FT_UInt)subr_no - 13 + ( subr_no == 18 );
|
||||
if ( arg_cnt != (FT_Int)( num_points * blend->num_designs ) )
|
||||
{
|
||||
FT_ERROR(( "t1_decoder_parse_charstrings: " ));
|
||||
FT_ERROR(( "incorrect number of mm arguments\n" ));
|
||||
goto Syntax_Error;
|
||||
}
|
||||
|
||||
top -= blend->num_designs * num_points;
|
||||
if ( top < decoder->stack )
|
||||
goto Stack_Underflow;
|
||||
|
||||
/* we want to compute: */
|
||||
/* */
|
||||
/* a0*w0 + a1*w1 + ... + ak*wk */
|
||||
@ -695,16 +748,178 @@
|
||||
|
||||
*values++ = tmp;
|
||||
}
|
||||
/* note that `top' will be incremented later by calls to `pop' */
|
||||
|
||||
known_othersubr_result_cnt = num_points;
|
||||
break;
|
||||
}
|
||||
|
||||
#ifdef CAN_HANDLE_NON_INTEGRAL_T1_OPERANDS
|
||||
|
||||
/* We cannot yet enable these since currently */
|
||||
/* our T1 stack stores integers which lack the */
|
||||
/* precision to express the values */
|
||||
|
||||
case 19:
|
||||
/* <idx> 1 19 callothersubr */
|
||||
/* => replace elements starting from index cvi( <idx> ) */
|
||||
/* of BuildCharArray with WeightVector */
|
||||
{
|
||||
FT_Int idx;
|
||||
PS_Blend blend = decoder->blend;
|
||||
|
||||
|
||||
if ( arg_cnt != 1 || blend == NULL )
|
||||
goto Unexpected_OtherSubr;
|
||||
|
||||
idx = top[0];
|
||||
|
||||
if ( idx < 0 ||
|
||||
idx + blend->num_designs > decoder->face->len_buildchar )
|
||||
goto Unexpected_OtherSubr;
|
||||
|
||||
memcpy( &decoder->buildchar[idx],
|
||||
blend->weight_vector,
|
||||
blend->num_designs *
|
||||
sizeof( blend->weight_vector[ 0 ] ) );
|
||||
}
|
||||
break;
|
||||
|
||||
case 20:
|
||||
/* <arg1> <arg2> 2 20 callothersubr pop */
|
||||
/* ==> push <arg1> + <arg2> onto T1 stack */
|
||||
if ( arg_cnt != 2 )
|
||||
goto Unexpected_OtherSubr;
|
||||
|
||||
top[0] += top[1]; /* XXX (over|under)flow */
|
||||
|
||||
known_othersubr_result_cnt = 1;
|
||||
break;
|
||||
|
||||
case 21:
|
||||
/* <arg1> <arg2> 2 21 callothersubr pop */
|
||||
/* ==> push <arg1> - <arg2> onto T1 stack */
|
||||
if ( arg_cnt != 2 )
|
||||
goto Unexpected_OtherSubr;
|
||||
|
||||
top[0] -= top[1]; /* XXX (over|under)flow */
|
||||
|
||||
known_othersubr_result_cnt = 1;
|
||||
break;
|
||||
|
||||
case 22:
|
||||
/* <arg1> <arg2> 2 22 callothersubr pop */
|
||||
/* ==> push <arg1> * <arg2> onto T1 stack */
|
||||
if ( arg_cnt != 2 )
|
||||
goto Unexpected_OtherSubr;
|
||||
|
||||
top[0] *= top[1]; /* XXX (over|under)flow */
|
||||
|
||||
known_othersubr_result_cnt = 1;
|
||||
break;
|
||||
|
||||
case 23:
|
||||
/* <arg1> <arg2> 2 23 callothersubr pop */
|
||||
/* ==> push <arg1> / <arg2> onto T1 stack */
|
||||
if ( arg_cnt != 2 || top[1] == 0 )
|
||||
goto Unexpected_OtherSubr;
|
||||
|
||||
top[0] /= top[1]; /* XXX (over|under)flow */
|
||||
|
||||
known_othersubr_result_cnt = 1;
|
||||
break;
|
||||
|
||||
#endif /* CAN_HANDLE_NON_INTEGRAL_T1_OPERANDS */
|
||||
|
||||
case 24:
|
||||
/* <val> <idx> 2 24 callothersubr */
|
||||
/* => set BuildCharArray[cvi( <idx> )] = <val> */
|
||||
{
|
||||
FT_Int idx;
|
||||
PS_Blend blend = decoder->blend;
|
||||
|
||||
if ( arg_cnt != 2 || blend == NULL )
|
||||
goto Unexpected_OtherSubr;
|
||||
|
||||
idx = top[1];
|
||||
|
||||
if ( idx < 0 || (FT_UInt) idx >= decoder->len_buildchar )
|
||||
goto Unexpected_OtherSubr;
|
||||
|
||||
decoder->buildchar[idx] = top[0];
|
||||
}
|
||||
break;
|
||||
|
||||
case 25:
|
||||
/* <idx> 1 25 callothersubr pop */
|
||||
/* => push BuildCharArray[cvi( idx )] */
|
||||
/* onto T1 stack */
|
||||
{
|
||||
FT_Int idx;
|
||||
PS_Blend blend = decoder->blend;
|
||||
|
||||
if ( arg_cnt != 1 || blend == NULL )
|
||||
goto Unexpected_OtherSubr;
|
||||
|
||||
idx = top[0];
|
||||
|
||||
if ( idx < 0 || (FT_UInt) idx >= decoder->len_buildchar )
|
||||
goto Unexpected_OtherSubr;
|
||||
|
||||
top[0] = decoder->buildchar[idx];
|
||||
}
|
||||
|
||||
known_othersubr_result_cnt = 1;
|
||||
break;
|
||||
|
||||
#if 0
|
||||
case 26:
|
||||
/* <val> mark <idx> ==> set BuildCharArray[cvi( <idx> )] = <val>, */
|
||||
/* leave mark on T1 stack */
|
||||
/* <val> <idx> ==> set BuildCharArray[cvi( <idx> )] = <val> */
|
||||
XXX who has left his mark on the (PostScript) stack ?;
|
||||
break;
|
||||
#endif
|
||||
|
||||
case 27:
|
||||
/* <res1> <res2> <val1> <val2> 4 27 callothersubr pop */
|
||||
/* ==> push <res1> onto T1 stack if <val1> <= <val2>, */
|
||||
/* otherwise push <res2> */
|
||||
if ( arg_cnt != 4 )
|
||||
goto Unexpected_OtherSubr;
|
||||
|
||||
if ( top[2] > top[3] )
|
||||
top[0] = top[1];
|
||||
|
||||
known_othersubr_result_cnt = 1;
|
||||
break;
|
||||
|
||||
#ifdef CAN_HANDLE_NON_INTEGRAL_T1_OPERANDS
|
||||
case 28:
|
||||
/* 0 28 callothersubr pop */
|
||||
/* => push random value from interval [0, 1) onto stack */
|
||||
if ( arg_cnt != 0 )
|
||||
goto Unexpected_OtherSubr;
|
||||
|
||||
top[0] = FT_rand();
|
||||
known_othersubr_result_cnt = 1;
|
||||
break;
|
||||
#endif
|
||||
|
||||
default:
|
||||
FT_ERROR(( "t1_decoder_parse_charstrings: "
|
||||
"unknown othersubr [%d %d], wish me luck!\n",
|
||||
arg_cnt, subr_no ));
|
||||
unknown_othersubr_result_cnt = arg_cnt;
|
||||
break;
|
||||
|
||||
Unexpected_OtherSubr:
|
||||
FT_ERROR(( "t1_decoder_parse_charstrings: "
|
||||
"invalid othersubr [%d %d]!\n", top[0], top[1] ));
|
||||
"invalid othersubr [%d %d]!\n", arg_cnt, subr_no ));
|
||||
goto Syntax_Error;
|
||||
}
|
||||
|
||||
top += known_othersubr_result_cnt;
|
||||
|
||||
decoder->top = top;
|
||||
}
|
||||
else /* general operator */
|
||||
@ -712,9 +927,38 @@
|
||||
FT_Int num_args = t1_args_count[op];
|
||||
|
||||
|
||||
FT_ASSERT( num_args >= 0 );
|
||||
|
||||
if ( top - decoder->stack < num_args )
|
||||
goto Stack_Underflow;
|
||||
|
||||
/* XXX Operators usually take their operands from the */
|
||||
/* bottom of the stack, i.e., the operands are */
|
||||
/* decoder->stack[0], ..., decoder->stack[num_args - 1]; */
|
||||
/* only div, callsubr, and callothersubr are different. */
|
||||
/* In practice it doesn't matter (?). */
|
||||
|
||||
#ifdef FT_DEBUG_LEVEL_TRACE
|
||||
|
||||
switch ( op )
|
||||
{
|
||||
case op_callsubr:
|
||||
case op_div:
|
||||
case op_callothersubr:
|
||||
case op_pop:
|
||||
case op_return:
|
||||
break;
|
||||
|
||||
default:
|
||||
if ( top - decoder->stack != num_args )
|
||||
FT_TRACE0(( "\nMore operands on the stack than expected "
|
||||
"(have %d, expected %d)\n",
|
||||
top - decoder->stack, num_args ));
|
||||
break;
|
||||
}
|
||||
|
||||
#endif /* FT_DEBUG_LEVEL_TRACE */
|
||||
|
||||
top -= num_args;
|
||||
|
||||
switch ( op )
|
||||
@ -740,8 +984,30 @@
|
||||
/* add current outline to the glyph slot */
|
||||
FT_GlyphLoader_Add( builder->loader );
|
||||
|
||||
FT_TRACE4(( "\n" ));
|
||||
|
||||
/* the compiler should optimize away this empty loop but ... */
|
||||
|
||||
#ifdef FT_DEBUG_LEVEL_TRACE
|
||||
|
||||
if ( decoder->len_buildchar > 0 )
|
||||
{
|
||||
FT_UInt i;
|
||||
|
||||
|
||||
FT_TRACE4(( "BuildCharArray = [ " ));
|
||||
|
||||
for ( i = 0; i < decoder->len_buildchar; ++i )
|
||||
FT_TRACE4(( "%d ", decoder->buildchar[ i ] ));
|
||||
|
||||
FT_TRACE4(( "]\n" ));
|
||||
}
|
||||
|
||||
#endif /* FT_DEBUG_LEVEL_TRACE */
|
||||
|
||||
FT_TRACE4(( "\n" ));
|
||||
|
||||
/* return now! */
|
||||
FT_TRACE4(( "\n\n" ));
|
||||
return PSaux_Err_Ok;
|
||||
|
||||
case op_hsbw:
|
||||
@ -997,8 +1263,22 @@
|
||||
case op_pop:
|
||||
FT_TRACE4(( " pop" ));
|
||||
|
||||
/* theoretically, the arguments are already on the stack */
|
||||
top++;
|
||||
if ( known_othersubr_result_cnt > 0 )
|
||||
{
|
||||
known_othersubr_result_cnt--;
|
||||
/* ignore, we pushed the operands ourselves */
|
||||
break;
|
||||
}
|
||||
|
||||
if ( unknown_othersubr_result_cnt == 0 )
|
||||
{
|
||||
FT_ERROR(( "t1_decoder_parse_charstrings: "
|
||||
"no more operands for othersubr!\n" ));
|
||||
goto Syntax_Error;
|
||||
}
|
||||
|
||||
unknown_othersubr_result_cnt--;
|
||||
top++; /* `push' the operand to callothersubr onto the stack */
|
||||
break;
|
||||
|
||||
case op_return:
|
||||
@ -1073,9 +1353,27 @@
|
||||
case op_setcurrentpoint:
|
||||
FT_TRACE4(( " setcurrentpoint" ));
|
||||
|
||||
FT_ERROR(( "t1_decoder_parse_charstrings: " ));
|
||||
FT_ERROR(( "unexpected `setcurrentpoint'\n" ));
|
||||
goto Syntax_Error;
|
||||
/* From the T1 specs, section 6.4: */
|
||||
/* */
|
||||
/* The setcurrentpoint command is used only in */
|
||||
/* conjunction with results from OtherSubrs procedures. */
|
||||
|
||||
/* known_othersubr_result_cnt != 0 is already handled above */
|
||||
if ( decoder->flex_state != 1 )
|
||||
{
|
||||
FT_ERROR(( "t1_decoder_parse_charstrings: " ));
|
||||
FT_ERROR(( "unexpected `setcurrentpoint'\n" ));
|
||||
|
||||
goto Syntax_Error;
|
||||
}
|
||||
else
|
||||
decoder->flex_state = 0;
|
||||
break;
|
||||
|
||||
case op_unknown15:
|
||||
FT_TRACE4(( " opcode_15" ));
|
||||
/* nothing to do except to pop the two arguments */
|
||||
break;
|
||||
|
||||
default:
|
||||
FT_ERROR(( "t1_decoder_parse_charstrings: "
|
||||
@ -1083,6 +1381,11 @@
|
||||
goto Syntax_Error;
|
||||
}
|
||||
|
||||
/* XXX Operators usually clear the operand stack; */
|
||||
/* only div, callsubr, callothersubr, pop, and */
|
||||
/* return are different. */
|
||||
/* In practice it doesn't matter (?). */
|
||||
|
||||
decoder->top = top;
|
||||
|
||||
} /* general operator processing */
|
||||
@ -1143,6 +1446,10 @@
|
||||
|
||||
t1_builder_init( &decoder->builder, face, size, slot, hinting );
|
||||
|
||||
/* decoder->buildchar and decoder->len_buildchar have to be */
|
||||
/* initialized by the caller since we cannot know the length */
|
||||
/* of the BuildCharArray */
|
||||
|
||||
decoder->num_glyphs = (FT_UInt)face->num_glyphs;
|
||||
decoder->glyph_names = glyph_names;
|
||||
decoder->hint_mode = hint_mode;
|
||||
@ -1151,7 +1458,7 @@
|
||||
|
||||
decoder->funcs = t1_decoder_funcs;
|
||||
|
||||
return 0;
|
||||
return PSaux_Err_Ok;
|
||||
}
|
||||
|
||||
|
||||
|
@ -4,7 +4,7 @@
|
||||
/* */
|
||||
/* PostScript hinting algorithm (body). */
|
||||
/* */
|
||||
/* Copyright 2001, 2002, 2003, 2004, 2005 by */
|
||||
/* Copyright 2001, 2002, 2003, 2004, 2005, 2006, 2007 by */
|
||||
/* David Turner, Robert Wilhelm, and Werner Lemberg. */
|
||||
/* */
|
||||
/* This file is part of the FreeType project, and may only be used */
|
||||
@ -19,6 +19,7 @@
|
||||
#include <ft2build.h>
|
||||
#include FT_INTERNAL_OBJECTS_H
|
||||
#include FT_INTERNAL_DEBUG_H
|
||||
#include FT_INTERNAL_CALC_H
|
||||
#include "pshalgo.h"
|
||||
|
||||
#include "pshnterr.h"
|
||||
@ -879,6 +880,104 @@
|
||||
/*************************************************************************/
|
||||
/*************************************************************************/
|
||||
|
||||
#if 1
|
||||
|
||||
#define psh_corner_is_flat ft_corner_is_flat
|
||||
#define psh_corner_orientation ft_corner_orientation
|
||||
|
||||
#else
|
||||
|
||||
FT_LOCAL_DEF( FT_Int )
|
||||
psh_corner_is_flat( FT_Pos x_in,
|
||||
FT_Pos y_in,
|
||||
FT_Pos x_out,
|
||||
FT_Pos y_out )
|
||||
{
|
||||
FT_Pos ax = x_in;
|
||||
FT_Pos ay = y_in;
|
||||
|
||||
FT_Pos d_in, d_out, d_corner;
|
||||
|
||||
|
||||
if ( ax < 0 )
|
||||
ax = -ax;
|
||||
if ( ay < 0 )
|
||||
ay = -ay;
|
||||
d_in = ax + ay;
|
||||
|
||||
ax = x_out;
|
||||
if ( ax < 0 )
|
||||
ax = -ax;
|
||||
ay = y_out;
|
||||
if ( ay < 0 )
|
||||
ay = -ay;
|
||||
d_out = ax + ay;
|
||||
|
||||
ax = x_out + x_in;
|
||||
if ( ax < 0 )
|
||||
ax = -ax;
|
||||
ay = y_out + y_in;
|
||||
if ( ay < 0 )
|
||||
ay = -ay;
|
||||
d_corner = ax + ay;
|
||||
|
||||
return ( d_in + d_out - d_corner ) < ( d_corner >> 4 );
|
||||
}
|
||||
|
||||
static FT_Int
|
||||
psh_corner_orientation( FT_Pos in_x,
|
||||
FT_Pos in_y,
|
||||
FT_Pos out_x,
|
||||
FT_Pos out_y )
|
||||
{
|
||||
FT_Int result;
|
||||
|
||||
|
||||
/* deal with the trivial cases quickly */
|
||||
if ( in_y == 0 )
|
||||
{
|
||||
if ( in_x >= 0 )
|
||||
result = out_y;
|
||||
else
|
||||
result = -out_y;
|
||||
}
|
||||
else if ( in_x == 0 )
|
||||
{
|
||||
if ( in_y >= 0 )
|
||||
result = -out_x;
|
||||
else
|
||||
result = out_x;
|
||||
}
|
||||
else if ( out_y == 0 )
|
||||
{
|
||||
if ( out_x >= 0 )
|
||||
result = in_y;
|
||||
else
|
||||
result = -in_y;
|
||||
}
|
||||
else if ( out_x == 0 )
|
||||
{
|
||||
if ( out_y >= 0 )
|
||||
result = -in_x;
|
||||
else
|
||||
result = in_x;
|
||||
}
|
||||
else /* general case */
|
||||
{
|
||||
long long delta = (long long)in_x * out_y - (long long)in_y * out_x;
|
||||
|
||||
if ( delta == 0 )
|
||||
result = 0;
|
||||
else
|
||||
result = 1 - 2 * ( delta < 0 );
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
#endif /* !1 */
|
||||
|
||||
|
||||
#ifdef COMPUTE_INFLEXS
|
||||
|
||||
/* compute all inflex points in a given glyph */
|
||||
@ -891,8 +990,8 @@
|
||||
for ( n = 0; n < glyph->num_contours; n++ )
|
||||
{
|
||||
PSH_Point first, start, end, before, after;
|
||||
FT_Angle angle_in, angle_seg, angle_out;
|
||||
FT_Angle diff_in, diff_out;
|
||||
FT_Pos in_x, in_y, out_x, out_y;
|
||||
FT_Int orient_prev, orient_cur;
|
||||
FT_Int finished = 0;
|
||||
|
||||
|
||||
@ -910,9 +1009,10 @@
|
||||
if ( end == first )
|
||||
goto Skip;
|
||||
|
||||
} while ( PSH_POINT_EQUAL_ORG( end, first ) );
|
||||
in_x = end->org_u - start->org_u;
|
||||
in_y = end->org_v - start->org_v;
|
||||
|
||||
angle_seg = PSH_POINT_ANGLE( start, end );
|
||||
} while ( in_x == 0 && in_y == 0 );
|
||||
|
||||
/* extend the segment start whenever possible */
|
||||
before = start;
|
||||
@ -925,14 +1025,18 @@
|
||||
if ( before == first )
|
||||
goto Skip;
|
||||
|
||||
} while ( PSH_POINT_EQUAL_ORG( before, start ) );
|
||||
out_x = start->org_u - before->org_u;
|
||||
out_y = start->org_v - before->org_v;
|
||||
|
||||
angle_in = PSH_POINT_ANGLE( before, start );
|
||||
} while ( out_x == 0 && out_y == 0 );
|
||||
|
||||
} while ( angle_in == angle_seg );
|
||||
orient_prev = psh_corner_orientation( in_x, in_y, out_x, out_y );
|
||||
|
||||
first = start;
|
||||
diff_in = FT_Angle_Diff( angle_in, angle_seg );
|
||||
} while ( orient_prev == 0 );
|
||||
|
||||
first = start;
|
||||
in_x = out_x;
|
||||
in_y = out_y;
|
||||
|
||||
/* now, process all segments in the contour */
|
||||
do
|
||||
@ -948,19 +1052,17 @@
|
||||
if ( after == first )
|
||||
finished = 1;
|
||||
|
||||
} while ( PSH_POINT_EQUAL_ORG( end, after ) );
|
||||
out_x = after->org_u - end->org_u;
|
||||
out_y = after->org_v - end->org_v;
|
||||
|
||||
angle_out = PSH_POINT_ANGLE( end, after );
|
||||
} while ( out_x == 0 && out_y == 0 );
|
||||
|
||||
} while ( angle_out == angle_seg );
|
||||
orient_cur = psh_corner_orientation( in_x, in_y, out_x, out_y );
|
||||
|
||||
diff_out = FT_Angle_Diff( angle_seg, angle_out );
|
||||
} while ( orient_cur == 0 );
|
||||
|
||||
if ( ( diff_in ^ diff_out ) < 0 )
|
||||
if ( ( orient_cur ^ orient_prev ) < 0 )
|
||||
{
|
||||
/* diff_in and diff_out have different signs, we have */
|
||||
/* inflection points here... */
|
||||
|
||||
do
|
||||
{
|
||||
psh_point_set_inflex( start );
|
||||
@ -971,10 +1073,11 @@
|
||||
psh_point_set_inflex( start );
|
||||
}
|
||||
|
||||
start = end;
|
||||
end = after;
|
||||
angle_seg = angle_out;
|
||||
diff_in = diff_out;
|
||||
start = end;
|
||||
end = after;
|
||||
orient_prev = orient_cur;
|
||||
in_x = out_x;
|
||||
in_y = out_y;
|
||||
|
||||
} while ( !finished );
|
||||
|
||||
@ -1199,28 +1302,11 @@
|
||||
/* detect smooth points */
|
||||
if ( point->flags & PSH_POINT_OFF )
|
||||
point->flags |= PSH_POINT_SMOOTH;
|
||||
else if ( point->dir_in != PSH_DIR_NONE ||
|
||||
point->dir_out != PSH_DIR_NONE )
|
||||
|
||||
else if ( point->dir_in == point->dir_out )
|
||||
{
|
||||
if ( point->dir_in == point->dir_out )
|
||||
point->flags |= PSH_POINT_SMOOTH;
|
||||
}
|
||||
else
|
||||
{
|
||||
FT_Angle angle_in, angle_out, diff;
|
||||
|
||||
|
||||
angle_in = FT_Atan2( dxi, dyi );
|
||||
angle_out = FT_Atan2( dxo, dyo );
|
||||
|
||||
diff = angle_in - angle_out;
|
||||
if ( diff < 0 )
|
||||
diff = -diff;
|
||||
|
||||
if ( diff > FT_ANGLE_PI )
|
||||
diff = FT_ANGLE_2PI - diff;
|
||||
|
||||
if ( diff < FT_ANGLE_PI / 16 )
|
||||
if ( point->dir_out != PSH_DIR_NONE ||
|
||||
psh_corner_is_flat( dxi, dyi, dxo, dyo ) )
|
||||
point->flags |= PSH_POINT_SMOOTH;
|
||||
}
|
||||
}
|
||||
@ -1382,115 +1468,147 @@
|
||||
/* -major_dir. */
|
||||
|
||||
static void
|
||||
psh_hint_table_find_strong_point( PSH_Hint_Table table,
|
||||
PSH_Point point,
|
||||
FT_Int threshold,
|
||||
FT_Int major_dir )
|
||||
psh_hint_table_find_strong_points( PSH_Hint_Table table,
|
||||
PSH_Point point,
|
||||
FT_UInt count,
|
||||
FT_Int threshold,
|
||||
FT_Int major_dir )
|
||||
{
|
||||
PSH_Hint* sort = table->sort;
|
||||
FT_UInt num_hints = table->num_hints;
|
||||
FT_Int point_dir = 0;
|
||||
|
||||
|
||||
if ( PSH_DIR_COMPARE( point->dir_in, major_dir ) )
|
||||
point_dir = point->dir_in;
|
||||
|
||||
else if ( PSH_DIR_COMPARE( point->dir_out, major_dir ) )
|
||||
point_dir = point->dir_out;
|
||||
|
||||
if ( point_dir )
|
||||
for ( ; count > 0; count--, point++ )
|
||||
{
|
||||
FT_UInt flag;
|
||||
FT_Int point_dir = 0;
|
||||
FT_Pos org_u = point->org_u;
|
||||
|
||||
|
||||
for ( ; num_hints > 0; num_hints--, sort++ )
|
||||
if ( psh_point_is_strong( point ) )
|
||||
continue;
|
||||
|
||||
if ( PSH_DIR_COMPARE( point->dir_in, major_dir ) )
|
||||
point_dir = point->dir_in;
|
||||
|
||||
else if ( PSH_DIR_COMPARE( point->dir_out, major_dir ) )
|
||||
point_dir = point->dir_out;
|
||||
|
||||
if ( point_dir )
|
||||
{
|
||||
PSH_Hint hint = sort[0];
|
||||
FT_Pos d;
|
||||
|
||||
|
||||
if ( point_dir == major_dir )
|
||||
{
|
||||
flag = PSH_POINT_EDGE_MIN;
|
||||
d = point->org_u - hint->org_pos;
|
||||
FT_UInt nn;
|
||||
|
||||
if ( FT_ABS( d ) < threshold )
|
||||
|
||||
for ( nn = 0; nn < num_hints; nn++ )
|
||||
{
|
||||
Is_Strong:
|
||||
psh_point_set_strong( point );
|
||||
point->flags2 |= flag;
|
||||
point->hint = hint;
|
||||
break;
|
||||
PSH_Hint hint = sort[nn];
|
||||
FT_Pos d = org_u - hint->org_pos;
|
||||
|
||||
|
||||
if ( d < threshold && -d < threshold )
|
||||
{
|
||||
psh_point_set_strong( point );
|
||||
point->flags2 |= PSH_POINT_EDGE_MIN;
|
||||
point->hint = hint;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
else if ( point_dir == -major_dir )
|
||||
{
|
||||
flag = PSH_POINT_EDGE_MAX;
|
||||
d = point->org_u - hint->org_pos - hint->org_len;
|
||||
FT_UInt nn;
|
||||
|
||||
if ( FT_ABS( d ) < threshold )
|
||||
goto Is_Strong;
|
||||
|
||||
for ( nn = 0; nn < num_hints; nn++ )
|
||||
{
|
||||
PSH_Hint hint = sort[nn];
|
||||
FT_Pos d = org_u - hint->org_pos - hint->org_len;
|
||||
|
||||
|
||||
if ( d < threshold && -d < threshold )
|
||||
{
|
||||
psh_point_set_strong( point );
|
||||
point->flags2 |= PSH_POINT_EDGE_MAX;
|
||||
point->hint = hint;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#if 1
|
||||
else if ( psh_point_is_extremum( point ) )
|
||||
{
|
||||
/* treat extrema as special cases for stem edge alignment */
|
||||
FT_UInt min_flag, max_flag;
|
||||
|
||||
|
||||
if ( major_dir == PSH_DIR_HORIZONTAL )
|
||||
else if ( psh_point_is_extremum( point ) )
|
||||
{
|
||||
min_flag = PSH_POINT_POSITIVE;
|
||||
max_flag = PSH_POINT_NEGATIVE;
|
||||
}
|
||||
else
|
||||
{
|
||||
min_flag = PSH_POINT_NEGATIVE;
|
||||
max_flag = PSH_POINT_POSITIVE;
|
||||
}
|
||||
/* treat extrema as special cases for stem edge alignment */
|
||||
FT_UInt nn, min_flag, max_flag;
|
||||
|
||||
for ( ; num_hints > 0; num_hints--, sort++ )
|
||||
{
|
||||
PSH_Hint hint = sort[0];
|
||||
FT_Pos d;
|
||||
FT_Int flag;
|
||||
|
||||
if ( major_dir == PSH_DIR_HORIZONTAL )
|
||||
{
|
||||
min_flag = PSH_POINT_POSITIVE;
|
||||
max_flag = PSH_POINT_NEGATIVE;
|
||||
}
|
||||
else
|
||||
{
|
||||
min_flag = PSH_POINT_NEGATIVE;
|
||||
max_flag = PSH_POINT_POSITIVE;
|
||||
}
|
||||
|
||||
if ( point->flags2 & min_flag )
|
||||
{
|
||||
flag = PSH_POINT_EDGE_MIN;
|
||||
d = point->org_u - hint->org_pos;
|
||||
|
||||
if ( FT_ABS( d ) < threshold )
|
||||
for ( nn = 0; nn < num_hints; nn++ )
|
||||
{
|
||||
Is_Strong2:
|
||||
point->flags2 |= flag;
|
||||
point->hint = hint;
|
||||
psh_point_set_strong( point );
|
||||
break;
|
||||
PSH_Hint hint = sort[nn];
|
||||
FT_Pos d = org_u - hint->org_pos;
|
||||
|
||||
|
||||
if ( d < threshold && -d < threshold )
|
||||
{
|
||||
point->flags2 |= PSH_POINT_EDGE_MIN;
|
||||
point->hint = hint;
|
||||
psh_point_set_strong( point );
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
else if ( point->flags2 & max_flag )
|
||||
{
|
||||
flag = PSH_POINT_EDGE_MAX;
|
||||
d = point->org_u - hint->org_pos - hint->org_len;
|
||||
for ( nn = 0; nn < num_hints; nn++ )
|
||||
{
|
||||
PSH_Hint hint = sort[nn];
|
||||
FT_Pos d = org_u - hint->org_pos - hint->org_len;
|
||||
|
||||
if ( FT_ABS( d ) < threshold )
|
||||
goto Is_Strong2;
|
||||
|
||||
if ( d < threshold && -d < threshold )
|
||||
{
|
||||
point->flags2 |= PSH_POINT_EDGE_MAX;
|
||||
point->hint = hint;
|
||||
psh_point_set_strong( point );
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if ( point->org_u >= hint->org_pos &&
|
||||
point->org_u <= hint->org_pos + hint->org_len )
|
||||
if ( point->hint == NULL )
|
||||
{
|
||||
point->hint = hint;
|
||||
for ( nn = 0; nn < num_hints; nn++ )
|
||||
{
|
||||
PSH_Hint hint = sort[nn];
|
||||
|
||||
|
||||
if ( org_u >= hint->org_pos &&
|
||||
org_u <= hint->org_pos + hint->org_len )
|
||||
{
|
||||
point->hint = hint;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#endif /* 1 */
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -1544,9 +1662,8 @@
|
||||
|
||||
psh_hint_table_activate_mask( table, mask );
|
||||
|
||||
for ( ; count > 0; count--, point++ )
|
||||
psh_hint_table_find_strong_point( table, point,
|
||||
threshold, major_dir );
|
||||
psh_hint_table_find_strong_points( table, point, count,
|
||||
threshold, major_dir );
|
||||
}
|
||||
first = next;
|
||||
}
|
||||
@ -1560,12 +1677,9 @@
|
||||
|
||||
|
||||
psh_hint_table_activate_mask( table, table->hint_masks->masks );
|
||||
for ( ; count > 0; count--, point++ )
|
||||
{
|
||||
if ( !psh_point_is_strong( point ) )
|
||||
psh_hint_table_find_strong_point( table, point,
|
||||
threshold, major_dir );
|
||||
}
|
||||
|
||||
psh_hint_table_find_strong_points( table, point, count,
|
||||
threshold, major_dir );
|
||||
}
|
||||
|
||||
/* now, certain points may have been attached to a hint and */
|
||||
@ -1710,6 +1824,8 @@
|
||||
}
|
||||
|
||||
|
||||
#define PSH_MAX_STRONG_INTERNAL 16
|
||||
|
||||
static void
|
||||
psh_glyph_interpolate_normal_points( PSH_Glyph glyph,
|
||||
FT_Int dimension )
|
||||
@ -1718,14 +1834,64 @@
|
||||
#if 1
|
||||
/* first technique: a point is strong if it is a local extremum */
|
||||
|
||||
PSH_Dimension dim = &glyph->globals->dimension[dimension];
|
||||
FT_Fixed scale = dim->scale_mult;
|
||||
PSH_Dimension dim = &glyph->globals->dimension[dimension];
|
||||
FT_Fixed scale = dim->scale_mult;
|
||||
FT_Memory memory = glyph->memory;
|
||||
|
||||
FT_UInt count = glyph->num_points;
|
||||
PSH_Point point = glyph->points;
|
||||
PSH_Point* strongs = NULL;
|
||||
PSH_Point strongs_0[PSH_MAX_STRONG_INTERNAL];
|
||||
FT_UInt num_strongs = 0;
|
||||
|
||||
PSH_Point points = glyph->points;
|
||||
PSH_Point points_end = points + glyph->num_points;
|
||||
PSH_Point point;
|
||||
|
||||
|
||||
for ( ; count > 0; count--, point++ )
|
||||
/* first count the number of strong points */
|
||||
for ( point = points; point < points_end; point++ )
|
||||
{
|
||||
if ( psh_point_is_strong( point ) )
|
||||
num_strongs++;
|
||||
}
|
||||
|
||||
if ( num_strongs == 0 ) /* nothing to do here */
|
||||
return;
|
||||
|
||||
/* allocate an array to store a list of points, */
|
||||
/* stored in increasing org_u order */
|
||||
if ( num_strongs <= PSH_MAX_STRONG_INTERNAL )
|
||||
strongs = strongs_0;
|
||||
else
|
||||
{
|
||||
FT_Error error;
|
||||
|
||||
|
||||
if ( FT_NEW_ARRAY( strongs, num_strongs ) )
|
||||
return;
|
||||
}
|
||||
|
||||
num_strongs = 0;
|
||||
for ( point = points; point < points_end; point++ )
|
||||
{
|
||||
PSH_Point* insert;
|
||||
|
||||
|
||||
if ( !psh_point_is_strong( point ) )
|
||||
continue;
|
||||
|
||||
for ( insert = strongs + num_strongs; insert > strongs; insert-- )
|
||||
{
|
||||
if ( insert[-1]->org_u <= point->org_u )
|
||||
break;
|
||||
|
||||
insert[0] = insert[-1];
|
||||
}
|
||||
insert[0] = point;
|
||||
num_strongs++;
|
||||
}
|
||||
|
||||
/* now try to interpolate all normal points */
|
||||
for ( point = points; point < points_end; point++ )
|
||||
{
|
||||
if ( psh_point_is_strong( point ) )
|
||||
continue;
|
||||
@ -1744,82 +1910,70 @@
|
||||
point->flags &= ~PSH_POINT_SMOOTH;
|
||||
}
|
||||
|
||||
/* find best enclosing point coordinates */
|
||||
/* find best enclosing point coordinates then interpolate */
|
||||
{
|
||||
PSH_Point before = 0;
|
||||
PSH_Point after = 0;
|
||||
|
||||
FT_Pos diff_before = -32000;
|
||||
FT_Pos diff_after = 32000;
|
||||
FT_Pos u = point->org_u;
|
||||
|
||||
FT_Int count2 = glyph->num_points;
|
||||
PSH_Point cur = glyph->points;
|
||||
PSH_Point before, after;
|
||||
FT_UInt nn;
|
||||
|
||||
|
||||
for ( ; count2 > 0; count2--, cur++ )
|
||||
for ( nn = 0; nn < num_strongs; nn++ )
|
||||
if ( strongs[nn]->org_u > point->org_u )
|
||||
break;
|
||||
|
||||
if ( nn == 0 ) /* point before the first strong point */
|
||||
{
|
||||
if ( psh_point_is_strong( cur ) )
|
||||
{
|
||||
FT_Pos diff = cur->org_u - u;
|
||||
after = strongs[0];
|
||||
|
||||
|
||||
if ( diff <= 0 )
|
||||
{
|
||||
if ( diff > diff_before )
|
||||
{
|
||||
diff_before = diff;
|
||||
before = cur;
|
||||
}
|
||||
}
|
||||
|
||||
else if ( diff >= 0 )
|
||||
{
|
||||
if ( diff < diff_after )
|
||||
{
|
||||
diff_after = diff;
|
||||
after = cur;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if ( !before )
|
||||
{
|
||||
if ( !after )
|
||||
continue;
|
||||
|
||||
/* we are before the first strong point coordinate; */
|
||||
/* simply translate the point */
|
||||
point->cur_u = after->cur_u +
|
||||
FT_MulFix( point->org_u - after->org_u, scale );
|
||||
}
|
||||
else if ( !after )
|
||||
{
|
||||
/* we are after the last strong point coordinate; */
|
||||
/* simply translate the point */
|
||||
point->cur_u = before->cur_u +
|
||||
FT_MulFix( point->org_u - before->org_u, scale );
|
||||
FT_MulFix( point->org_u - after->org_u,
|
||||
scale );
|
||||
}
|
||||
else
|
||||
{
|
||||
if ( diff_before == 0 )
|
||||
point->cur_u = before->cur_u;
|
||||
before = strongs[nn - 1];
|
||||
|
||||
else if ( diff_after == 0 )
|
||||
point->cur_u = after->cur_u;
|
||||
for ( nn = num_strongs; nn > 0; nn-- )
|
||||
if ( strongs[nn - 1]->org_u < point->org_u )
|
||||
break;
|
||||
|
||||
if ( nn == num_strongs ) /* point is after last strong point */
|
||||
{
|
||||
before = strongs[nn - 1];
|
||||
|
||||
else
|
||||
point->cur_u = before->cur_u +
|
||||
FT_MulDiv( u - before->org_u,
|
||||
after->cur_u - before->cur_u,
|
||||
after->org_u - before->org_u );
|
||||
}
|
||||
FT_MulFix( point->org_u - before->org_u,
|
||||
scale );
|
||||
}
|
||||
else
|
||||
{
|
||||
FT_Pos u;
|
||||
|
||||
|
||||
after = strongs[nn];
|
||||
|
||||
/* now interpolate point between before and after */
|
||||
u = point->org_u;
|
||||
|
||||
if ( u == before->org_u )
|
||||
point->cur_u = before->cur_u;
|
||||
|
||||
else if ( u == after->org_u )
|
||||
point->cur_u = after->cur_u;
|
||||
|
||||
else
|
||||
point->cur_u = before->cur_u +
|
||||
FT_MulDiv( u - before->org_u,
|
||||
after->cur_u - before->cur_u,
|
||||
after->org_u - before->org_u );
|
||||
}
|
||||
}
|
||||
psh_point_set_fitted( point );
|
||||
}
|
||||
}
|
||||
|
||||
if ( strongs != strongs_0 )
|
||||
FT_FREE( strongs );
|
||||
|
||||
#endif /* 1 */
|
||||
|
||||
}
|
||||
|
@ -182,11 +182,12 @@
|
||||
|
||||
/* Build a table that maps Unicode values to glyph indices. */
|
||||
static FT_Error
|
||||
ps_unicodes_init( FT_Memory memory,
|
||||
PS_Unicodes table,
|
||||
FT_UInt num_glyphs,
|
||||
PS_Glyph_NameFunc get_glyph_name,
|
||||
FT_Pointer glyph_data )
|
||||
ps_unicodes_init( FT_Memory memory,
|
||||
PS_Unicodes table,
|
||||
FT_UInt num_glyphs,
|
||||
PS_GetGlyphNameFunc get_glyph_name,
|
||||
PS_FreeGlyphNameFunc free_glyph_name,
|
||||
FT_Pointer glyph_data )
|
||||
{
|
||||
FT_Error error;
|
||||
|
||||
@ -220,6 +221,9 @@
|
||||
map->glyph_index = n;
|
||||
map++;
|
||||
}
|
||||
|
||||
if ( free_glyph_name )
|
||||
free_glyph_name( glyph_data, gname );
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -4,7 +4,7 @@
|
||||
/* */
|
||||
/* The FreeType glyph rasterizer (body). */
|
||||
/* */
|
||||
/* Copyright 1996-2001, 2002, 2003, 2005 by */
|
||||
/* Copyright 1996-2001, 2002, 2003, 2005, 2007 by */
|
||||
/* David Turner, Robert Wilhelm, and Werner Lemberg. */
|
||||
/* */
|
||||
/* This file is part of the FreeType project, and may only be used, */
|
||||
@ -378,19 +378,19 @@
|
||||
#else /* FT_STATIC_RASTER */
|
||||
|
||||
|
||||
#define RAS_ARGS TRaster_Instance* raster,
|
||||
#define RAS_ARG TRaster_Instance* raster
|
||||
#define RAS_ARGS PWorker worker,
|
||||
#define RAS_ARG PWorker worker
|
||||
|
||||
#define RAS_VARS raster,
|
||||
#define RAS_VAR raster
|
||||
#define RAS_VARS worker,
|
||||
#define RAS_VAR worker
|
||||
|
||||
#define FT_UNUSED_RASTER FT_UNUSED( raster )
|
||||
#define FT_UNUSED_RASTER FT_UNUSED( worker )
|
||||
|
||||
|
||||
#endif /* FT_STATIC_RASTER */
|
||||
|
||||
|
||||
typedef struct TRaster_Instance_ TRaster_Instance;
|
||||
typedef struct TWorker_ TWorker, *PWorker;
|
||||
|
||||
|
||||
/* prototypes used for sweep function dispatch */
|
||||
@ -422,7 +422,7 @@
|
||||
/* at the top. Thus, their offset can be coded with less */
|
||||
/* opcodes, and it results in a smaller executable. */
|
||||
|
||||
struct TRaster_Instance_
|
||||
struct TWorker_
|
||||
{
|
||||
Int precision_bits; /* precision related variables */
|
||||
Int precision;
|
||||
@ -498,15 +498,9 @@
|
||||
TBand band_stack[16]; /* band stack used for sub-banding */
|
||||
Int band_top; /* band stack top */
|
||||
|
||||
Int count_table[256]; /* Look-up table used to quickly count */
|
||||
/* set bits in a gray 2x2 cell */
|
||||
|
||||
void* memory;
|
||||
|
||||
#ifdef FT_RASTER_OPTION_ANTI_ALIASING
|
||||
|
||||
Byte grays[5]; /* Palette of gray levels used for */
|
||||
/* render. */
|
||||
Byte* grays;
|
||||
|
||||
Byte gray_lines[RASTER_GRAY_LINES];
|
||||
/* Intermediate table used to render the */
|
||||
@ -523,30 +517,53 @@
|
||||
|
||||
#endif /* FT_RASTER_ANTI_ALIASING */
|
||||
|
||||
#if 0
|
||||
PByte flags; /* current flags table */
|
||||
PUShort outs; /* current outlines table */
|
||||
FT_Vector* coords;
|
||||
|
||||
UShort nPoints; /* number of points in current glyph */
|
||||
Short nContours; /* number of contours in current glyph */
|
||||
#endif
|
||||
|
||||
};
|
||||
|
||||
|
||||
typedef struct TRaster_
|
||||
{
|
||||
char* buffer;
|
||||
long buffer_size;
|
||||
void* memory;
|
||||
PWorker worker;
|
||||
Byte grays[5];
|
||||
Short gray_width;
|
||||
|
||||
} TRaster, *PRaster;
|
||||
|
||||
#ifdef FT_STATIC_RASTER
|
||||
|
||||
static TRaster_Instance cur_ras;
|
||||
static TWorker cur_ras;
|
||||
#define ras cur_ras
|
||||
|
||||
#else
|
||||
|
||||
#define ras (*raster)
|
||||
#define ras (*worker)
|
||||
|
||||
#endif /* FT_STATIC_RASTER */
|
||||
|
||||
|
||||
static const char count_table[256] =
|
||||
{
|
||||
0 , 1 , 1 , 2 , 1 , 2 , 2 , 3 , 1 , 2 , 2 , 3 , 2 , 3 , 3 , 4,
|
||||
1 , 2 , 2 , 3 , 2 , 3 , 3 , 4 , 2 , 3 , 3 , 4 , 3 , 4 , 4 , 5,
|
||||
1 , 2 , 2 , 3 , 2 , 3 , 3 , 4 , 2 , 3 , 3 , 4 , 3 , 4 , 4 , 5,
|
||||
2 , 3 , 3 , 4 , 3 , 4 , 4 , 5 , 3 , 4 , 4 , 5 , 4 , 5 , 5 , 6,
|
||||
1 , 2 , 2 , 3 , 2 , 3 , 3 , 4 , 2 , 3 , 3 , 4 , 3 , 4 , 4 , 5,
|
||||
2 , 3 , 3 , 4 , 3 , 4 , 4 , 5 , 3 , 4 , 4 , 5 , 4 , 5 , 5 , 6,
|
||||
2 , 3 , 3 , 4 , 3 , 4 , 4 , 5 , 3 , 4 , 4 , 5 , 4 , 5 , 5 , 6,
|
||||
3 , 4 , 4 , 5 , 4 , 5 , 5 , 6 , 4 , 5 , 5 , 6 , 5 , 6 , 6 , 7,
|
||||
1 , 2 , 2 , 3 , 2 , 3 , 3 , 4 , 2 , 3 , 3 , 4 , 3 , 4 , 4 , 5,
|
||||
2 , 3 , 3 , 4 , 3 , 4 , 4 , 5 , 3 , 4 , 4 , 5 , 4 , 5 , 5 , 6,
|
||||
2 , 3 , 3 , 4 , 3 , 4 , 4 , 5 , 3 , 4 , 4 , 5 , 4 , 5 , 5 , 6,
|
||||
3 , 4 , 4 , 5 , 4 , 5 , 5 , 6 , 4 , 5 , 5 , 6 , 5 , 6 , 6 , 7,
|
||||
2 , 3 , 3 , 4 , 3 , 4 , 4 , 5 , 3 , 4 , 4 , 5 , 4 , 5 , 5 , 6,
|
||||
3 , 4 , 4 , 5 , 4 , 5 , 5 , 6 , 4 , 5 , 5 , 6 , 5 , 6 , 6 , 7,
|
||||
3 , 4 , 4 , 5 , 4 , 5 , 5 , 6 , 4 , 5 , 5 , 6 , 5 , 6 , 6 , 7,
|
||||
4 , 5 , 5 , 6 , 5 , 6 , 6 , 7 , 5 , 6 , 6 , 7 , 6 , 7 , 7 , 8 };
|
||||
|
||||
|
||||
|
||||
/*************************************************************************/
|
||||
/*************************************************************************/
|
||||
/** **/
|
||||
@ -2494,7 +2511,7 @@
|
||||
{
|
||||
Int c1, c2;
|
||||
PByte pix, bit, bit2;
|
||||
Int* count = ras.count_table;
|
||||
char* count = (char*)count_table;
|
||||
Byte* grays;
|
||||
|
||||
|
||||
@ -3153,32 +3170,19 @@
|
||||
|
||||
|
||||
static void
|
||||
ft_black_init( TRaster_Instance* raster )
|
||||
ft_black_init( PRaster raster )
|
||||
{
|
||||
FT_UInt n;
|
||||
FT_ULong c;
|
||||
|
||||
|
||||
/* setup count table */
|
||||
for ( n = 0; n < 256; n++ )
|
||||
{
|
||||
c = ( n & 0x55 ) + ( ( n & 0xAA ) >> 1 );
|
||||
|
||||
c = ( ( c << 6 ) & 0x3000 ) |
|
||||
( ( c << 4 ) & 0x0300 ) |
|
||||
( ( c << 2 ) & 0x0030 ) |
|
||||
(c & 0x0003 );
|
||||
|
||||
ras.count_table[n] = (UInt)c;
|
||||
}
|
||||
FT_UNUSED( raster );
|
||||
|
||||
#ifdef FT_RASTER_OPTION_ANTI_ALIASING
|
||||
FT_UInt n;
|
||||
|
||||
|
||||
/* set default 5-levels gray palette */
|
||||
for ( n = 0; n < 5; n++ )
|
||||
raster->grays[n] = n * 255 / 4;
|
||||
|
||||
ras.gray_width = RASTER_GRAY_LINES / 2;
|
||||
raster->gray_width = RASTER_GRAY_LINES / 2;
|
||||
|
||||
#endif
|
||||
}
|
||||
@ -3195,7 +3199,7 @@
|
||||
ft_black_new( void* memory,
|
||||
FT_Raster *araster )
|
||||
{
|
||||
static TRaster_Instance the_raster;
|
||||
static TRaster the_raster;
|
||||
|
||||
|
||||
*araster = (FT_Raster)&the_raster;
|
||||
@ -3218,11 +3222,11 @@
|
||||
|
||||
|
||||
static int
|
||||
ft_black_new( FT_Memory memory,
|
||||
TRaster_Instance** araster )
|
||||
ft_black_new( FT_Memory memory,
|
||||
PRaster *araster )
|
||||
{
|
||||
FT_Error error;
|
||||
TRaster_Instance* raster;
|
||||
FT_Error error;
|
||||
PRaster raster;
|
||||
|
||||
|
||||
*araster = 0;
|
||||
@ -3239,7 +3243,7 @@
|
||||
|
||||
|
||||
static void
|
||||
ft_black_done( TRaster_Instance* raster )
|
||||
ft_black_done( PRaster raster )
|
||||
{
|
||||
FT_Memory memory = (FT_Memory)raster->memory;
|
||||
FT_FREE( raster );
|
||||
@ -3250,21 +3254,34 @@
|
||||
|
||||
|
||||
static void
|
||||
ft_black_reset( TRaster_Instance* raster,
|
||||
char* pool_base,
|
||||
long pool_size )
|
||||
ft_black_reset( PRaster raster,
|
||||
char* pool_base,
|
||||
long pool_size )
|
||||
{
|
||||
if ( (&ras) && pool_base && pool_size >= 4096 )
|
||||
if ( raster )
|
||||
{
|
||||
/* save the pool */
|
||||
ras.buff = (PLong)pool_base;
|
||||
ras.sizeBuff = ras.buff + pool_size / sizeof ( Long );
|
||||
if ( pool_base && pool_size >= (long)sizeof(TWorker) + 2048 )
|
||||
{
|
||||
PWorker worker = (PWorker)pool_base;
|
||||
|
||||
|
||||
raster->buffer = pool_base + ( (sizeof ( *worker ) + 7 ) & ~7 );
|
||||
raster->buffer_size = ( ( pool_base + pool_size ) -
|
||||
(char*)raster->buffer ) / sizeof ( Long );
|
||||
raster->worker = worker;
|
||||
}
|
||||
else
|
||||
{
|
||||
raster->buffer = NULL;
|
||||
raster->buffer_size = 0;
|
||||
raster->worker = NULL;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
ft_black_set_mode( TRaster_Instance* raster,
|
||||
ft_black_set_mode( PRaster raster,
|
||||
unsigned long mode,
|
||||
const char* palette )
|
||||
{
|
||||
@ -3273,11 +3290,11 @@
|
||||
if ( mode == FT_MAKE_TAG( 'p', 'a', 'l', '5' ) )
|
||||
{
|
||||
/* set 5-levels gray palette */
|
||||
ras.grays[0] = palette[0];
|
||||
ras.grays[1] = palette[1];
|
||||
ras.grays[2] = palette[2];
|
||||
ras.grays[3] = palette[3];
|
||||
ras.grays[4] = palette[4];
|
||||
raster->grays[0] = palette[0];
|
||||
raster->grays[1] = palette[1];
|
||||
raster->grays[2] = palette[2];
|
||||
raster->grays[3] = palette[3];
|
||||
raster->grays[4] = palette[4];
|
||||
}
|
||||
|
||||
#else
|
||||
@ -3291,14 +3308,15 @@
|
||||
|
||||
|
||||
static int
|
||||
ft_black_render( TRaster_Instance* raster,
|
||||
ft_black_render( PRaster raster,
|
||||
const FT_Raster_Params* params )
|
||||
{
|
||||
const FT_Outline* outline = (const FT_Outline*)params->source;
|
||||
const FT_Bitmap* target_map = params->target;
|
||||
PWorker worker;
|
||||
|
||||
|
||||
if ( !(&ras) || !ras.buff || !ras.sizeBuff )
|
||||
if ( !raster || !raster->buffer || !raster->buffer_size )
|
||||
return Raster_Err_Not_Ini;
|
||||
|
||||
/* return immediately if the outline is empty */
|
||||
@ -3311,6 +3329,8 @@
|
||||
if ( outline->n_points != outline->contours[outline->n_contours - 1] + 1 )
|
||||
return Raster_Err_Invalid;
|
||||
|
||||
worker = raster->worker;
|
||||
|
||||
/* this version of the raster does not support direct rendering, sorry */
|
||||
if ( params->flags & FT_RASTER_FLAG_DIRECT )
|
||||
return Raster_Err_Unsupported;
|
||||
@ -3321,6 +3341,14 @@
|
||||
ras.outline = *outline;
|
||||
ras.target = *target_map;
|
||||
|
||||
worker->buff = (PLong) raster->buffer;
|
||||
worker->sizeBuff = worker->buff +
|
||||
raster->buffer_size / sizeof ( Long );
|
||||
#ifdef FT_RASTER_OPTION_ANTI_ALIASING
|
||||
worker->grays = raster->grays;
|
||||
worker->gray_width = raster->gray_width;
|
||||
#endif
|
||||
|
||||
return ( ( params->flags & FT_RASTER_FLAG_AA )
|
||||
? Render_Gray_Glyph( RAS_VAR )
|
||||
: Render_Glyph( RAS_VAR ) );
|
||||
|
@ -3,7 +3,7 @@
|
||||
#
|
||||
|
||||
|
||||
# Copyright 1996-2000, 2002, 2003, 2004, 2005, 2006 by
|
||||
# Copyright 1996-2000, 2002, 2003, 2004, 2005, 2006, 2007 by
|
||||
# David Turner, Robert Wilhelm, and Werner Lemberg.
|
||||
#
|
||||
# This file is part of the FreeType project, and may only be used, modified,
|
||||
|
@ -412,9 +412,9 @@
|
||||
{
|
||||
FT_UNUSED( face );
|
||||
FT_UNUSED( stream );
|
||||
|
||||
|
||||
return FT_Err_Unimplemented_Feature;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
FT_CALLBACK_DEF( void )
|
||||
@ -449,8 +449,8 @@
|
||||
|
||||
*astrike_index = 0x7FFFFFFFUL;
|
||||
|
||||
return tt_face_set_sbit_strike( face, &req, astrike_index );
|
||||
}
|
||||
return tt_face_set_sbit_strike( face, &req, astrike_index );
|
||||
}
|
||||
|
||||
|
||||
FT_CALLBACK_DEF( FT_Error )
|
||||
@ -459,15 +459,15 @@
|
||||
{
|
||||
FT_UNUSED( face );
|
||||
FT_UNUSED( stream );
|
||||
|
||||
|
||||
/*
|
||||
* This function was originally implemented to load the sbit table.
|
||||
* This function was originally implemented to load the sbit table.
|
||||
* However, it has been replaced by `tt_face_load_eblc', and this stub
|
||||
* is only there for some rogue clients which would want to call it
|
||||
* directly (which doesn't make much sense).
|
||||
*/
|
||||
return FT_Err_Unimplemented_Feature;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
FT_CALLBACK_DEF( void )
|
||||
@ -476,8 +476,8 @@
|
||||
/* nothing to do in this stub */
|
||||
FT_UNUSED( face );
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
FT_CALLBACK_DEF( FT_Error )
|
||||
tt_face_load_charmap_stub( TT_Face face,
|
||||
void* cmap,
|
||||
@ -486,9 +486,9 @@
|
||||
FT_UNUSED( face );
|
||||
FT_UNUSED( cmap );
|
||||
FT_UNUSED( input );
|
||||
|
||||
|
||||
return FT_Err_Unimplemented_Feature;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
FT_CALLBACK_DEF( FT_Error )
|
||||
@ -497,10 +497,10 @@
|
||||
{
|
||||
FT_UNUSED( face );
|
||||
FT_UNUSED( cmap );
|
||||
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
#endif /* FT_CONFIG_OPTION_OLD_INTERNALS */
|
||||
|
||||
|
||||
@ -600,7 +600,7 @@
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
#endif
|
||||
#endif
|
||||
|
||||
tt_face_get_metrics
|
||||
};
|
||||
|
@ -4,7 +4,7 @@
|
||||
/* */
|
||||
/* SFNT object management (base). */
|
||||
/* */
|
||||
/* Copyright 1996-2001, 2002, 2003, 2004, 2005, 2006 by */
|
||||
/* Copyright 1996-2001, 2002, 2003, 2004, 2005, 2006, 2007 by */
|
||||
/* David Turner, Robert Wilhelm, and Werner Lemberg. */
|
||||
/* */
|
||||
/* This file is part of the FreeType project, and may only be used, */
|
||||
@ -75,37 +75,6 @@
|
||||
}
|
||||
|
||||
|
||||
/* convert a UCS-4 name entry to ASCII */
|
||||
static FT_String*
|
||||
tt_name_entry_ascii_from_ucs4( TT_NameEntry entry,
|
||||
FT_Memory memory )
|
||||
{
|
||||
FT_String* string;
|
||||
FT_UInt len, code, n;
|
||||
FT_Byte* read = (FT_Byte*)entry->string;
|
||||
FT_Error error;
|
||||
|
||||
|
||||
len = (FT_UInt)entry->stringLength / 4;
|
||||
|
||||
if ( FT_NEW_ARRAY( string, len + 1 ) )
|
||||
return NULL;
|
||||
|
||||
for ( n = 0; n < len; n++ )
|
||||
{
|
||||
code = (FT_UInt)FT_NEXT_ULONG( read );
|
||||
if ( code < 32 || code > 127 )
|
||||
code = '?';
|
||||
|
||||
string[n] = (char)code;
|
||||
}
|
||||
|
||||
string[len] = 0;
|
||||
|
||||
return string;
|
||||
}
|
||||
|
||||
|
||||
/* convert an Apple Roman or symbol name entry to ASCII */
|
||||
static FT_String*
|
||||
tt_name_entry_ascii_from_other( TT_NameEntry entry,
|
||||
@ -165,9 +134,11 @@
|
||||
FT_String* result = NULL;
|
||||
FT_UShort n;
|
||||
TT_NameEntryRec* rec;
|
||||
FT_Int found_apple = -1;
|
||||
FT_Int found_win = -1;
|
||||
FT_Int found_unicode = -1;
|
||||
FT_Int found_apple = -1;
|
||||
FT_Int found_apple_roman = -1;
|
||||
FT_Int found_apple_english = -1;
|
||||
FT_Int found_win = -1;
|
||||
FT_Int found_unicode = -1;
|
||||
|
||||
FT_Bool is_english = 0;
|
||||
|
||||
@ -200,9 +171,14 @@
|
||||
break;
|
||||
|
||||
case TT_PLATFORM_MACINTOSH:
|
||||
/* This is a bit special because some fonts will use either */
|
||||
/* an English language id, or a Roman encoding id, to indicate */
|
||||
/* the English version of its font name. */
|
||||
/* */
|
||||
if ( rec->languageID == TT_MAC_LANGID_ENGLISH )
|
||||
found_apple = n;
|
||||
|
||||
found_apple_english = n;
|
||||
else if ( rec->encodingID == TT_MAC_ID_ROMAN )
|
||||
found_apple_roman = n;
|
||||
break;
|
||||
|
||||
case TT_PLATFORM_MICROSOFT:
|
||||
@ -232,6 +208,10 @@
|
||||
}
|
||||
}
|
||||
|
||||
found_apple = found_apple_roman;
|
||||
if ( found_apple_english >= 0 )
|
||||
found_apple = found_apple_english;
|
||||
|
||||
/* some fonts contain invalid Unicode or Macintosh formatted entries; */
|
||||
/* we will thus favor names encoded in Windows formats if available */
|
||||
/* (provided it is an English name) */
|
||||
@ -242,13 +222,19 @@
|
||||
rec = face->name_table.names + found_win;
|
||||
switch ( rec->encodingID )
|
||||
{
|
||||
/* all Unicode strings are encoded using UTF-16BE */
|
||||
case TT_MS_ID_UNICODE_CS:
|
||||
case TT_MS_ID_SYMBOL_CS:
|
||||
convert = tt_name_entry_ascii_from_utf16;
|
||||
break;
|
||||
|
||||
case TT_MS_ID_UCS_4:
|
||||
convert = tt_name_entry_ascii_from_ucs4;
|
||||
/* Apparently, if this value is found in a name table entry, it is */
|
||||
/* documented as `full Unicode repertoire'. Experience with the */
|
||||
/* MsGothic font shipped with Windows Vista shows that this really */
|
||||
/* means UTF-16 encoded names (UCS-4 values are only used within */
|
||||
/* charmaps). */
|
||||
convert = tt_name_entry_ascii_from_utf16;
|
||||
break;
|
||||
|
||||
default:
|
||||
@ -915,7 +901,7 @@
|
||||
FT_UInt i, count;
|
||||
|
||||
|
||||
#if defined FT_OPTIMIZE_MEMORY && !defined FT_CONFIG_OPTION_OLD_INTERNALS
|
||||
#if !defined FT_CONFIG_OPTION_OLD_INTERNALS
|
||||
count = face->sbit_num_strikes;
|
||||
#else
|
||||
count = (FT_UInt)face->num_sbit_strikes;
|
||||
@ -1022,7 +1008,7 @@
|
||||
}
|
||||
|
||||
/* freeing the horizontal metrics */
|
||||
#if defined FT_OPTIMIZE_MEMORY && !defined FT_CONFIG_OPTION_OLD_INTERNALS
|
||||
#if !defined FT_CONFIG_OPTION_OLD_INTERNALS
|
||||
{
|
||||
FT_Stream stream = FT_FACE_STREAM( face );
|
||||
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
x
Reference in New Issue
Block a user